微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何防止 Ruby 的倒排字符类匹配换行符?

如何解决如何防止 Ruby 的倒排字符类匹配换行符?

TLDR:当禁用多行匹配时,如何让 Ruby 的正则表达式引擎从倒置字符类中排除换行符?

背景

对于我使用过的大多数正则表达式引擎,除非指定了多行修饰符,否则不可能跨行匹配。 . 运算符应该匹配除换行符之外的任何字符,并且倒置字符类 ([^x]) 也不应该匹配换行符。例如,使用 ripgrep:

printf "a\nb\nc\nd" | rg '^a.*b.*c.*d$'
# [no output]

printf "a\nb\nc\nd" | rg '^a[^x]*b[^x]*c[^x]*d$'
# [no output]

^$ 运算符应该匹配任何行的开头和结尾,而不仅仅是整个字符串,如下所示:

printf "a\nb\nc\nd" | rg '^c$'
# c

使用多行选项,ripgrep 可以跨行匹配:

printf "a\nb\nc\nd" | rg --multiline --multiline-dotall '^a.*b.*c.*d$'
# a
# b
# c
# d

printf "a\nb\nc\nd" | rg --multiline --multiline-dotall '^a[^x]*b[^x]*c[^x]*d$'
# a
# b
# c
# d

Ruby 也不允许 . 匹配换行符,除非存在 m 修饰符,并且 ^$ 运算符可以匹配字符串中的任何行:

"a\nb\nc\nd".match(/^a.*b.*c.*d/)
# => nil

"a\nb\nc\nd".match(/^c$/)
# => #<MatchData "c">

"a\nb\nc\nd".match(/^a.*b.*c.*d/m)
# => #<MatchData "a\nb\nc\nd">

问题

然而,Ruby 的正则表达式引擎在给定倒置字符类时匹配换行符,即使没有多行修饰符。这是非常出乎意料的!

# This should return nil!
"a\nb\nc\nd".match(/^a[^x]*b[^x]*c[^x]*d$/)
# => #<MatchData "a\nb\nc\nd">

"a\nb\nc\nd".match(/^a[^x]*b[^x]*c[^x]*d$/m)
# => #<MatchData "a\nb\nc\nd">

我尝试过 Ruby 1.9.3、2.7.2 和 3.0,它们都表现出这种行为。所以这在 Ruby 中已经存在很长时间了。

问题

在为生成多行文本的内容编写规范时,我经常使用正则表达式。每当我使用倒置字符类时都必须指定 \n 对工作效率的影响非常大,并且违反了最小惊讶原则。

那么,当禁用多行匹配时,如何让 Ruby 的正则表达式引擎从倒置字符类中排除换行符?

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?