我正在尝试使用 StringScanner
将字符串解析为标记以便稍后处理。在我测试正则表达式语法解析之前,一切都很顺利。 Regexen 看起来像这样:
r|hello|gmi
r:there|there:gmi
r/:(?=[jedi])[sith]:/gmi
r!hello!gmi
也就是说,r
,然后是 |
(或其他几个字符,但现在不相关),然后是正则表达式的主体——可以包括转义字符,如 \|
和 \\
-- 然后是另一个 |
,然后是正则表达式的标志。
为了查找正则表达式文字,我使用的代码看起来非常像这样:
require 'strscan'
scanner = StringScanner.new('r|abc| ')
puts "pre-regex: #{scanner.inspect}"
puts "got a char: #{scanner.getch} (res: #{scanner.inspect})"
divider = scanner.getch
puts "got divider: #{divider.inspect}"
puts "mid-regex: #{scanner.inspect}"
# this bit still fails even if you replace `#{divider}' with `|'
res = scanner.scan_until(/(?<![^\\]\\)#{divider}[a-z]*/)
puts "post-regex: #{scanner.inspect}"
if scanner.skip(/\s+/)# || scanner.skip(/;-.*?-;/m)
puts "Success! #{res}"
else
puts "Fail. Ended at: #{scanner.inspect}"
puts "(res was #{res.inspect})"
end
在这里,我尽可能地减少了它以清楚地显示问题。在实际代码中,它是一大段代码的一部分,其中绝大多数是不相关的。我已将错误缩小到这部分——您可以使用链接查看它的存在——但我无法弄清楚为什么在 |
的下一个实例之前无法正确扫描>,然后返回标志。
顺便说一下,如果有更好的方法,请告诉我。我发现我非常喜欢 StringScanner
,但这可能是因为我对正则表达式很着迷,以至于我称它们为正则表达式。
TL;DR:为什么 StringScanner
显然是匹配的,就好像它的位置向后一个字符一样,我怎样才能让它正常工作?
最佳答案
例如,问题是 Ruby 按原样用字符串插入正则表达式
divider = '|'
/(?<![^\\]\\)#{divider}[a-z]*/
=> /(?<![^\\]\\)|[a-z]*/
要避开分隔线,你可以
divider = '|'
/(?<![^\\]\\)#{Regexp.quote divider}[a-z]*/
=> /(?<![^\\]\\)\|[a-z]*/
并且这样修改使得代码通过了,但是你还需要验证一个分隔符是一个非单词字符。
关于ruby - StringScanner 正在匹配一个字符串,就好像它向后一个位置一样,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36587653/