Perl 中的多行模式与 Ruby 不同: Ruby 是错误的?

Multiline mode in Perl and Ruby different: Ruby is wrong?

让我们看看 Perl 代码和结果:

$s = "a\nb\nc\n";
$s =~ s/^b/X/;
print $s;

a
b
c

$s = "a\nb\nc\n";
$s =~ s/^b/X/m;
print $s;

a
X
c

我认为Perl是对的,^只在启用多行时匹配中间换行后的位置。

让我们看看Ruby:

$s = "a\nb\nc\n"
print $s.sub(/^b/,'X')

a
X
c

$s = "a\nb\nc\n"
print $s.sub(/^b/m,'X')

a
X
c

无论是否处于多行模式,^ 都匹配文本中间换行后的位置。

我这辈子找不到 Ruby 定义多行选项功能的文档,它在哪里?

还有Ruby没有单行模式?

undefined group option: /(?s)^b/

/^b./s 会解析,但它的行为不像 Perl(。匹配新行)。

PS:我使用 Perl 5 和 Ruby 3.0 进行了测试。

I think Perl is right, ^ matches the position after new line in the middle only when multiline is enabled.

是的,没错。根据 man perlre, section Metacharacters^ 锚表示:

Match the beginning of the string (or line, if /m is used)

Let us look at Ruby: […] The ^ matches the position after newline in the middle of text regardless if it is in multiline mode or not.

也正确。根据 the documentation of the Regexp class, section Anchors:

^ - Matches beginning of line

For the life of me, I cannot find Ruby documentation which defines what the multiline option will do, where is it?

the documentation of the Regexp class, section Options:

/pat/m - Treat a newline as a character matched by .

Also Ruby has no Single line mode (s)?

在 Ruby 中,您可以通过在模式前面加上破折号 - 来停用模式。因此,如果您当前处于多行模式,并且想返回单行模式,则不需要单独的模式。您可以使用 -m.

再次关闭多行模式

Ruby 和 Perl 的 /m 工作方式不同。


Ruby 的 /m 仅更改 . 的行为。它等同于 Perl 的 /s.

  • Ruby /m: 将换行符视为与 .

    匹配的字符
  • Perl /s: 将字符串视为单行。也就是改“。”匹配任何字符,甚至是通常不匹配的换行符。

Perl 的 /m 改变了 ^$ 的行为。

  • Perl /m: 将匹配的字符串视为多行。即,将“^”和“$”从匹配字符串第一行的开头和最后一行的结尾更改为匹配字符串中每一行的开头和结尾。

^$ 在 Ruby 中总是这样工作。 Ruby 实际上总是有 Perl 的 /m.

Ruby 和 Perl 都共享 \A\z\Z 以匹配字符串的开头、字符串的结尾或紧接在最后换行。

哪个是正确的?也不是,他们各行其是。 Perl 对 ^$ 的默认行为与 POSIX regular expressions, but they are incompatible in other ways. Python uses the equivalent of Perl's multi and single-line modes (MULTILINE and DOTALL 相同。 Ruby 简化了 ^$ 的行为并使正则表达式更加明确。

另请参阅