2009-08-27 117 views
0

语言是红宝石,这里是我的IRB会议为什么我的正则表达式中的最后一个表达式连接到第一个表达式?

expr = /\Aselect from (\D+)(?: (?:where|&&) (\D+) (\S+) (\S+))*(?: order by (\D+) (asc|desc))?\Z/ 
=> /\Aselect from (\D+)(?: (?:where|&&) (\D+) (\S+) (\S+))*(?: order by (\D+) (asc|desc))?\Z/ 

/> str = "select from Entity order by value desc" 
=> "select from Entity order by value desc" 

/> expr =~ str 
=> 0 

/> $1 
=> "Entity order by value desc" 

/> $2 
=> nil 

我只是不明白,为什么我是“按价值递减实体令”得到$ 1美元。这里期望的行为是获得$ 1 =>“实体”,$ 2 =>“值”,$ 3 =>“desc”。我究竟做错了什么?我如何修改这个正则表达式,以便得到这些结果?

谢谢

回答

4

\ d是“非数字”,它涵盖了下列词语词之间的空白,以及。尝试(\ S +)来代替。

[编辑]抱歉,我错过了最后的问题。以上回答'为什么会发生这种情况?',但不是'我如何实现我想要的?'。这里有一种方法,绕过任何其他条款与*

/\Aselect from (\S+).*(?:order by (\S+) (asc|desc)?)?\Z/ 

由于SQL与间距相当自由,这样的关键字之间,你可能想使它更不可读,并使用\ S +,而不是字面空间。也就是说,表达,是将不匹配:

"select from  Fred" 

,但它将如果你没有/ \ ASELECT \ S +从\ S + ....

1

(\D+)既贪婪又吃了字符串的其余部分。由于表达式中的所有内容都是可选的(*或?),因此表达式无需匹配即可成功。

我的建议是让你的比赛少贪心。例如(\D+?)将会匹配并捕获任何非数字一次或多次,但是根据需要只需要几次即可成功匹配。

相关问题