我使用的是ruby 2.1,但同样的东西可以在rubular网站上复制。
如果这是我的字符串:
儘管中國婦幼衛生監測辦公室制定的
我和这个表达式进行正则表达式匹配:
(中國婦幼衛生監測辦公室制定|管中)
我希望得到更长的令牌作为匹配。
中國婦幼衛生監測辦公室制定
相反,我将第二次轮换作为匹配。
据我所知,当不是中文字符时,它确实有效。
如果这是我的字符串:
foobar
我使用这个正则表达式:
(foobar|foo)
返回的匹配结果为foobar
。如果订单是另一种方式,那么匹配的字符串是foo
。这对我来说很有意义。
答案 0 :(得分:15)
您认为正则表达式与较长的交替匹配是不正确的。
快速复习:正则表达式如何工作:状态机始终从左向右读取,必要时回溯。
有两个指针,一个在模式上:
(cdefghijkl|bcd)
你的字符串上的另一个:
abcdefghijklmnopqrstuvw
String上的指针从左侧移动。一旦它可以返回,它将:
x http://gyazo.com/ac652df1ed094be6c5d66c14a2728ac1.png
让我们把它变成一个更“顺序”的序列来理解:
y http://gyazo.com/386aecb351fc2eb34f9c5db269a66dab.png
您的foobar
示例是另一个主题。正如我提到的in this post:
正则表达式的工作原理:状态机始终从左向右读取。
,|,, == ,
,因为它始终只与第一次轮换相匹配。
这很好,Unihedron,但是如何强制它进行第一次轮换呢?
看<!SUP> *
^(?:.*?\Kcdefghijkl|.*?\Kbcd)
这里有regex demo。
此正则表达式首先尝试将整个字符串与第一个字符串进行匹配。只有当它完全失败时,它才会尝试匹配第二次更改。 \K
用于保持与背后的内容构建\K
的匹配。
*
:从2.0.0开始,Ruby支持\K
。
了解详情:
啊,我很无聊,所以我优化了正则表达式:
^(?:(?:(?!cdefghijkl)c?[^c]*)++\Kcdefghijkl|(?:(?!bcd)b?[^b]*)++\Kbcd)
您可以看到演示here。