ruby - StringScanner 正在匹配一个字符串,就好像它向后一个位置一样

标签 ruby regex tokenize

我正在尝试使用 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

Try it online at ideone

在这里,我尽可能地减少了它以清楚地显示问题。在实际代码中,它是一大段代码的一部分,其中绝大多数是不相关的。我已将错误缩小到这部分——您可以使用链接查看它的存在——但我无法弄清楚为什么在 | 的下一个实例之前无法正确扫描>,然后返回标志。

顺便说一下,如果有更好的方法,请告诉我。我发现我非常喜欢 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/

相关文章:

ruby-on-rails - 需要用另一种语言为 Rails 生产应用程序编写代码吗?

ruby-on-rails - 如何从 html 创建多页 pdf

c++ - 从字符串中提取数字 C++

ruby - Mongoid 不删除 Mongo 对象

花括号之间的Java正则表达式匹配

regex - 如何删除字符串第一次出现之前和最后一次出现之后的所有行?

java - 无数字 Java 正则表达式模式

c++ - C/C++ 中的快速字符串标记化

一元前缀运算符的 Java 消歧

ruby-on-rails - 如何使用 Opal 生成示例 Rails 应用程序?