0

我正在尝试在 Perl 中编写一个正则表达式,该表达式适用于混合了文本和帐号的文本文件。我想做的是重新格式化帐号。.*当给定行上有多个匹配项时,我遇到了一个问题,即在帐号的任一侧进行匹配。我已经进行了一些搜索,但找不到任何答案,所以我希望有人可以向我解释我的正则表达式有什么问题,这样我就可以在将来避免这个陷阱。

while(<>) {

    s/(.*)\b([0-9]+)\b(.*)/$1xxx\-$2$3/g;
    print;
}

xxx-被帐户标识符替换,但在我让它工作之前,我只有x's.

我遇到的问题是,只有最后一次出现被替换,而不是所有出现。

例如,一个简单的示例行:

First Part 223456 Third Part Fourth Part 113456 Fifth Part Sixth Part

我希望:

First Part xxx-223456 Third Part Fourth Part xxx-113456 Fifth Part Sixth Part

但我只得到:

First Part 223456 Third Part Fourth Part xxx-113456 Fifth Part Sixth Part

如果我在捕获组中包含其他元字符它可以工作,我将它缩小到.* 问题,但我不能保证文件中的内容,所以我需要匹配所有内容。只有在同一行有多个帐号时才会发生这种情况;如果帐号出现在多行上,它工作正常。

任何反馈将不胜感激

4

4 回答 4

2

如果帐号只是数字,请执行以下操作:

s/\b(\d+)\b/xxx-$1/g;

如果它们总是 6 个数字,请更具体:s/\b(\d{6})\b/xxx-$1/g;

于 2013-02-18T17:18:28.587 回答
2

(.*)消耗输入中的所有字符,然后必须开始回溯:返回一个字符并测试下一个模式是否匹配,如果不匹配,则返回另一个字符并逐个字符检查匹配。

因此,通过将贪婪的通用匹配作为您的第一个表达式,您实际上是在要求引擎只找到最后一个匹配。你可能不知道你在要求这个,但你是。

通常,在处理正则表达式时,您必须考虑数据:“我将如何识别文件中的这种模式。很可能,“一位或多位数字”只是不会将其用于帐号,因此请指定你想匹配的模式尽你所能指定它。然后你可以确定如果有东西匹配你的模式,它很可能是你想要的。顺便说一下,单词边界规范是一个好的开始。

如果您需要准确的六位数,则指定准确的六位数

您不必指定(.*)为匹配的一部分的另一个原因是,从外观上看,您正在做您认为需要做的事情,以将线路的其他部分保持在原位。但是,Perl 只用替换替换匹配的部分。除了要匹配的部分之外,您无需指定任何内容

因此,假设您的帐号是 6 位宽,这就是您所需要的。

 s/\b(\d{6})\b/xxx-$1/g;

最后一点。如果由于某种原因您的正则表达式会找到您的第一个匹配项,在模式(.*) 之后指定,保证您每行只找到一个匹配项,并且/g不会应用,因为它使完全匹配等于输入行。

于 2013-02-18T18:31:52.870 回答
1

我看到的问题是贪婪匹配(.*) which in your case will match everything up until the last ([0-9]word boundary)。我想你可以把它关掉,你应该没问题(eg. s/(.*?)//g)

这是一个小例子:

while(my $line = <$fh>) {
    $line =~ s/(.*?)\b([0-9]+)\b(.*?)/$1xxx\-$2$3/g;
    print $line;
}

OUTPUT:
First Part xxx-223456 Third Part Fourth Part xxx-113456 Fifth Part Sixth Part
First Part xxx-223456 Third Part Fourth Part xxx-113456 Fifth Part Sixth Part
First Part xxx-223456 Third Part Fourth Part 
First Part xxx-223456
于 2013-02-18T17:35:51.543 回答
0

一种使用消极后瞻和另一种积极前瞻的方法:

perl -pe 's/(?<!\d)(\d+)(?=\D|$)/xxx-$1/g' <<<"First Part 223456 Third Part Fourth Part 113456 Fifth Part Sixth Part"

它产生:

First Part xxx-223456 Third Part Fourth Part xxx-113456 Fifth Part Sixth Part
于 2013-02-18T17:24:12.767 回答