Ruby 为什么正则表达式中的最后一个表达式连接到第一个?

Ruby 为什么正则表达式中的最后一个表达式连接到第一个?,ruby,regex,Ruby,Regex,语言是Ruby,下面是我的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

语言是Ruby,下面是我的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=>“描述”。我做错了什么?如何修改此正则表达式以获得这些结果

谢谢

\D是“非数字”,它包括单词之间的空格以及以下单词。请改为尝试(\S+)

[编辑]对不起,我错过了最后的问题。以上回答的是“为什么会发生这种情况?”,而不是“我如何实现我想要的?”。这里有一种方法,用一个*

/\Aselect from (\S+).*(?:order by (\S+) (asc|desc)?)?\Z/
由于SQL对关键字之间的空格和类似空格非常自由,因此您可能希望使其更不可读,并使用\s+而不是文字空格。也就是说,表达式as is不匹配:

"select   from     Fred"
但是如果您这样做了/\Aselect\s+from\s+..

\D是“非数字”,它覆盖了单词之间的空白以及以下单词。请改为尝试(\S+)

[编辑]对不起,我错过了最后的问题。以上回答的是“为什么会发生这种情况?”,而不是“我如何实现我想要的?”。这里有一种方法,用一个*

/\Aselect from (\S+).*(?:order by (\S+) (asc|desc)?)?\Z/
由于SQL对关键字之间的空格和类似空格非常自由,因此您可能希望使其更不可读,并使用\s+而不是文字空格。也就是说,表达式as is不匹配:

"select   from     Fred"
但是如果您从\s+..

中选择了\s+,
(\D+)
会很贪婪,并且已经吃掉了字符串的其余部分。由于表达式中的所有其他内容都是可选的(*或?),因此表达式无需匹配它即可成功

我的建议是让你的火柴不那么贪婪。例如,
(\D+?)
将匹配并捕获任何非数字一次或多次,但匹配成功所需的次数应尽可能少。

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

我的建议是让你的火柴不那么贪婪。例如,
(\D+?)
将匹配并捕获任何非数字一次或多次,但匹配成功所需的次数应尽可能少