Perl 正则表达式多行匹配没有点

Posted

技术标签:

【中文标题】Perl 正则表达式多行匹配没有点【英文标题】:Perl regex multiline match without dot 【发布时间】:2016-05-24 13:53:08 【问题描述】:

关于如何在 Perl 中执行多行正则表达式有很多问题。他们中的大多数都提到了使点匹配换行符的s 开关。但是,我想匹配一个确切的短语(所以,不是模式),我不知道换行符在哪里。所以问题是:你能忽略换行符,而不是将它们与.匹配吗?

MWE:

$pattern = "Match this exact phrase across newlines";

$text1 = "Match\nthis exact\nphrase across newlines";
$text2 = "Match this\nexact phra\nse across\nnewlines";

$text3 = "Keep any newlines\nMatch this exact\nphrase across newlines\noutside\nof the match";

$text1 =~ s/$pattern/replacement text/s;
$text2 =~ s/$pattern/replacement text/s;
$text3 =~ s/$pattern/replacement text/s;

print "$text1\n---\n$text2\n---\n$text3\n";

我可以在模式中放置点而不是空格 ("Match.this.exact.phrase"),但这不适用于第二个示例。我可以删除所有换行符作为预处理,但我想保留不属于匹配的换行符(如第三个示例所示)。

期望的输出:

replacement text
---
replacement text
---
Keep any newlines
replacement text
outside
of the match

【问题讨论】:

大多数时候,您将换行符视为空格。然后有一次你想忽略它。做任何一个都很容易。两者都做几乎是不可能的。 【参考方案1】:

只需将文字空格替换为与空格或换行符匹配的字符类:

$pattern = "Match[ \n]this[ \n]exact[ \n]phrase[ \n]across[ \n]newlines";

或者,如果您想更宽松,请改用\s\s+,因为\s 也匹配换行符。

【讨论】:

我的第二个例子(phra\nse)怎么样?【参考方案2】:

大多数时候,您将换行符视为空格。如果这就是你想做的,那么你所需要的就是

$text =~ s/\n/ /g;
$text =~ /\Q$text_to_find/    # or $text =~ /$regex_pattern_to_match/

然后有一次你想忽略它。如果这就是你想做的,那么你所需要的就是

$text =~ s/\n//g;
$text =~ /\Q$text_to_find/    # or $text =~ /$regex_pattern_to_match/

如果你有一个正则表达式模式要匹配,那么两者都做几乎是不可能的。但是您似乎想匹配文字文本,这样就开辟了一些可能性。

( my $pattern = $text_to_find )
   =~ s/(.)/ $1 eq " " ? "[ \\n]" : "\\n?" . quotemeta($1) /seg;
$pattern =~ s/^\\n\?//;
$text =~ /$pattern/

【讨论】:

经过测试。做了几个修复。 我认为这会在所需匹配之前删除换行符【参考方案3】:

听起来您想更改“精确”模式以匹配任何地方的换行符,并且还允许换行符而不是空格。所以改变你的模式来这样做:

$pattern = "Match this exact phrase across newlines";
$pattern =~ s/\S\K\B/\n?/g;
$pattern =~ s/ /[ \n]/g;

【讨论】:

注意:这里假定$pattern 不是正则表达式模式,而是要准确查找的字符串文字。 这不匹配$pattern = "*"$text = "*" 如果$pattern = "foo-bar"$text = "foo\n-bar" 将不匹配。 @ikegami 我假设没有正则表达式元字符,是的。但不要考虑其他非单词字符。改用ikegami的答案【参考方案4】:

它确实很丑,但它有效:

M\n?a\n?t\n?c\n?h\st\n?h\n?i\n?s\se\n?x\n?a\n?ct\sp\n?h\n?r\n?a\n?s\n?e\sa\n?c\n?r\n?o\n?s\n?s\sn\n?e\n?w\n?l\n?i\n?n\n?e\n?s

对于单词中的每一对字母,在它们之间允许使用\n? 换行。并将正则表达式中的每个空格替换为\s

可能无法使用,但它可以完成工作;)

Check it out at regex101.

【讨论】:

以上是关于Perl 正则表达式多行匹配没有点的主要内容,如果未能解决你的问题,请参考以下文章

perl 正则表达式 匹配多行的问题

Perl正则表达式匹配多行文件与匹配变量如何处理换行

perl多个正则表达式匹配多行

perl 正则表达式 模糊匹配

Perl 正则表达式匹配大型 Unicode 代码点

Python: 正则表达式匹配多行,实现多行匹配模式