当我匹配并替换Perl中的几个单词时,如何保留空格?
-
07-07-2019 - |
题
假设我有一些原始文本:
here is some text that has a substring that I'm interested in embedded in it.
我需要文本与其中的一部分匹配,例如:“有一个子字符串
”。
但是,原始文本和匹配字符串可能存在空格差异。例如,匹配文本可能是:
has a substring
或
has a substring
和/或原始文本可能是:
here is some text that has a substring that I'm interested in embedded in it.
我需要输出的程序是:
here is some text that [match starts here]has a substring[match ends here] that I'm interested in embedded in it.
我还需要保留原始空白模式,只需添加开始和结束标记。
有关使用Perl正则表达式实现此方法的任何想法?我试过了,但最终却感到非常困惑。
解决方案
自从我使用perl正则表达式以来已经过了一段时间,但是:
$match = s/(has\s+a\s+substring)/[$1]/ig
这将捕获单词之间的零个或多个空格和换行符。它将用括号包围整个匹配,同时保持原始分隔。它不是自动的,但确实有效。
你可以用这个玩游戏,比如把字符串"有一个子字符串"
并对它进行转换以使它" has \ s * a \ s * substring&quot ;
使这一点不那么痛苦。
编辑:合并了ysth的评论,即\ s元字符匹配换行符和hobbs更正我的用法。
其他提示
此模式将匹配您要查找的字符串:
(has\s+a\s+substring)
因此,当用户输入搜索字符串时,用 \ s +
替换搜索字符串中的任何空格,即可获得模式。只需用 [match starts here] $ 1 [匹配到此处]
替换每个匹配,其中 $ 1
是匹配的文本。
在正则表达式中,您可以使用 +
来表示“一个或多个”。像这样的东西
/has\s+a\s+substring/
匹配 has
后跟一个或多个空格字符,然后是 a
,后跟一个或多个空格字符,后跟 substring
。
将其与替换运算符放在一起,您可以说:
my $str = "here is some text that has a substring that I'm interested in embedded in it.";
$str =~ s/(has\s+a\s+substring)/\[match starts here]$1\[match ends here]/gs;
print $str;
输出是:
here is some text that [match starts here]has a substring[match ends here] that I'm interested in embedded in it.
许多人建议,使用 \ s +
来匹配空格。以下是您自动执行此操作的方法:
my $original = "here is some text that has a substring that I'm interested in embedded in it.";
my $search = "has a\nsubstring";
my $re = $search;
$re =~ s/\s+/\\s+/g;
$original =~ s/\b$re\b/[match starts here]<*>amp;[match ends here]/g;
print $original;
输出:
这里有一些[匹配从这里开始]有一个子字符串[匹配到此处],我有兴趣嵌入其中。
您可能想要转义字符串中的任何元字符。如果有人感兴趣,我可以添加它。
这是你如何做到这一点的一个例子。
#! /opt/perl/bin/perl
use strict;
use warnings;
my $submatch = "has a\nsubstring";
my $str = "
here is some
text that has
a substring that I'm interested in, embedded in it.
";
print substr_match($str, $submatch), "\n";
sub substr_match{
my($string,$match) = @_;
$match =~ s/\s+/\\s+/g;
# This isn't safe the way it is now, you will need to sanitize $match
$string =~ /\b$match\b/;
}
目前,这可以检查 $ match
变量中的不安全字符。