3

我正在处理一个多行字符串,带有 Unix (\n) 换行符。

它的一些行具有“A,a”的形式(即大写字母、逗号、空格、小写字母),我想从字符串中删除这些。

我可以通过正则表达式替换来完成此操作,但有一个我不明白的谜团:

使用“[AZ]”和“[az]”的正则表达式可以在普通模式和多行模式下工作。

使用 "\p{Lu}" 和 "\p{Ll}" 的正则表达式有效,但仅适用于普通模式,而不适用于多行模式。

这些成功中的每一个:

$all =~ s/\n\K *[A-Z], [a-z]\n//g;    # 1

$all =~ s/^ *[A-Z], [a-z]\n//mg;      # 2

$all =~ s/\n\K *\p{Lu}, \p{Ll}\n//g;  # 3

但这失败了:

$all =~ s/^ *\p{Lu}, \p{Ll}\n//mg;    # 4

我希望 /m 开关改变正则表达式中“^”的含义,但没有别的。所以,我希望语句 4 能够正常工作,就像语句 1、2 和 3 一样。语句 2 似乎表明多行语法是可以的,而语句 3 似乎表明 Unicode 字符属性符合预期,所以,当我结合这些时,我希望语句 4 能够工作。

我看过汤姆克里斯滕森的回答为什么现代 Perl 默认避免使用 UTF-8?,但我没有看到任何关于多行正则表达式匹配的信息,我也没有在其他地方找到答案。

4

1 回答 1

3

我无法复制您的问题。

$ perl -wle'
   $all = "foo\n  A, x\nmeow";
   $all =~ s/^ *[A-Z], [a-z]\n//mg;
   print $all;
'
foo
meow

$ perl -wle'
   $all = "foo\n  A, x\nmeow";
   $all =~ s/^ *\p{Lu}, \p{Ll}\n//mg;
   print $all;
'
foo
meow

在 Linux 上使用 5.8.8、5.10.1、5.12.4(线程)和 5.16.0 进行了测试。

最佳猜测:pos($all)不为零。也许你做了一些愚蠢的事情if ($all =~ /.../g)


我一开始也无法复制空格。

$ perl -wle'
   $all = "foo\nA, x\nmeow";
   $all =~ s/^ *[A-Z], [a-z]\n//mg;
   print $all;
'
foo
meow

$ perl -wle'
   $all = "foo\n  A, x\nmeow";
   $all =~ s/^ *\p{Lu}, \p{Ll}\n//mg;
   print $all;
'
foo
meow

在 cygwin 上使用 5.10.1(线程)测试。

>perl -wle"$all = qq{foo\nA, x\nmeow}; $all =~ s/^ *[A-Z], [a-z]\n//mg; print $all;"
foo
meow

>perl -wle"$all = qq{foo\nA, x\nmeow}; $all =~ s/^ *\p{Lu}, \p{Ll}\n//mg; print $all;"
foo
meow

在 Windows (ActivePerl) 上使用 5.14.0(线程)和 5.14.2(线程)测试。

但是,啊哈!!!!

>perl -wle"$all = qq{foo\nA, x\nmeow}; $all =~ s/^ *[A-Z], [a-z]\n//mg; print $all;"
foo
meow

>perl -wle"$all = qq{foo\nA, x\nmeow}; $all =~ s/^ *\p{Lu}, \p{Ll}\n//mg; print $all;"
foo
A, x
meow

在 Windows (ActivePerl) 上使用 5.10.1(线程)、5.12.1(线程)和 5.12.4(线程)进行了测试。

旧版本的 Perl 似乎有一个错误。它似乎已在 5.14 中修复。该错误似乎在优化器中(如 所示-Mre=debug),因此可以通过“禁用”优化器来绕过它。

>perl -wle"$all = qq{foo\nA, x\nmeow}; $all =~ s/^ *\p{Lu}, \p{Ll}\n//mg; print $all;"
foo
A, x
meow

>perl -wle"$all = qq{foo\nA, x\nmeow}; $all =~ s/^ *\p{Lu}{1}, \p{Ll}\n//mg; print $all;"
foo
meow
于 2012-08-02T22:11:48.067 回答