drK*_*eso 5 ruby regex string alternation regex-alternation
我使用的是ruby 2.1,但同样的东西可以在rubular网站上复制.
如果这是我的字符串:
????????????????
Run Code Online (Sandbox Code Playgroud)
我用这个表达式进行正则表达式匹配:
(?????????????|??)
Run Code Online (Sandbox Code Playgroud)
我期待得到更长的令牌作为匹配.
?????????????
Run Code Online (Sandbox Code Playgroud)
相反,我得到第二次替换作为匹配.
据我所知,它不像中文字符那样工作.
如果这是我的字符串:
foobar
Run Code Online (Sandbox Code Playgroud)
我使用这个正则表达式:
(foobar|foo)
Run Code Online (Sandbox Code Playgroud)
返回匹配结果是foobar
.如果顺序是另一种方式,那么匹配的字符串就是foo
.这对我来说很有意义.
Uni*_*ron 15
您认为正则表达式匹配较长的交替是不正确的.
快速复习:正则表达式如何工作:状态机始终从左到右读取,必要时回溯.
有两个指针,一个在模式上:
(cdefghijkl|bcd)
Run Code Online (Sandbox Code Playgroud)
你的字符串上的另一个:
abcdefghijklmnopqrstuvw
Run Code Online (Sandbox Code Playgroud)
String上的指针从左侧移动.只要它可以返回,它将会:
x http://gyazo.com/ac652df1ed094be6c5d66c14a2728ac1.png
让我们把它变成一个更"顺序"的序列来理解:
y http://gyazo.com/386aecb351fc2eb34f9c5db269a66dab.png
您的foobar
示例是另一个主题.正如我在这篇文章中提到的:
正则表达式如何工作:状态机始终从左到右读取.
,|,, == ,
,因为它始终只与第一次交替匹配.
那是好的,Unihedron,但是如何强制它进行第一次轮换呢?
看!*
^(?:.*?\Kcdefghijkl|.*?\Kbcd)
Run Code Online (Sandbox Code Playgroud)
这里有一个正则表达式演示.
此正则表达式首先尝试将整个字符串与第一个交替进行匹配.只有当它完全失败时,它才会尝试匹配第二次交替.\K
这里用于保持与构造后面的内容匹配\K
.
*
:\K
从2.0.0开始在Ruby中得到支持.
阅读更多:
啊,我很无聊,所以我优化了正则表达式:
^(?:(?:(?!cdefghijkl)c?[^c]*)++\Kcdefghijkl|(?:(?!bcd)b?[^b]*)++\Kbcd)
Run Code Online (Sandbox Code Playgroud)
你可以在这里看到一个演示.