Perl正则表达式排除字符串中间的某些字符串

时间:2019-06-14 15:27:47

标签: regex perl

我有这个字符串:

The file FILENAME has not been received

我正在尝试获取正则表达式来匹配它,但是如果字符串是这个(例如),则不会:

The file FAILNAME has not been received

到目前为止,我已经有了此正则表达式:

/^(?=.*?\bThe\sfile\b)((?!FAILNAME).)*$/

但是我不确定排除后如何继续预期的文本。

我希望我已经正确解释了:)

谢谢!

3 个答案:

答案 0 :(得分:3)

我将分两个步骤进行操作:

if ($message =~ /\AThe file (\S+) has not been received\z/ && $1 ne 'FAILNAME') {

即使用正则表达式验证通用格式并提取文件名,然后分别检查提取的名称。

为什么将所有内容都填充到单个正则表达式中?

说到这,您实际上可以将任意条件放入正则表达式中。在这种情况下,我不建议这样做,但是:

/\AThe file (\S+) has not been received\z(?(?{ $1 eq 'FAILNAME' })(*FAIL))/

此扩展模式实质上是“如果$1等于FAILNAME,则匹配失败”。

答案 1 :(得分:2)

您可以将否定的前瞻移至file之后,后跟一个空白字符,以断定右边的不是FAILNAME

^The\sfile\s(?!\bFAILNAME\b).*$

The file使用量词后,它不能出现在字符串中:

^The\sfile\s(?!.*\bFAILNAME\b).*$

如果FAILNAME前后没有任何内容,则可以环顾四周:

^The\sfile\s(?!.*(?<!\S)FAILNAME(?!\S)).*$

Regex demo

答案 2 :(得分:-1)

我的猜测是,我们希望使那些具有FAILNAME的字符(您的原始表达式似乎运行良好)失败,然后我们对其稍作修改,这可能会起作用:

^(?=The\sfile\s)(?!.*\s\bFAILNAME\b\s.*).*$

Demo 1

在这里,我们添加了两个空格作为额外的左边界和右边界,如果我们不希望有这些边界,则可以简单地排除。

示例

use strict;

my $str = 'The file FILENAME has not been received
The file FILENAME has been received
The file FILENAME
The file AFAILNAME has not been received
FILENAME
The file FAILNAME has not been received
FAILNAME has not been received
The file FAILNAME


';
my $regex = qr/^(?=The\sfile\s)(?!.*\s\bFAILNAME\b\s.*).*$/mp;

if ( $str =~ /$regex/g ) {
  print "Whole match is ${^MATCH} and its start/end positions can be obtained via \$-[0] and \$+[0]\n";
  # print "Capture Group 1 is $1 and its start/end positions can be obtained via \$-[1] and \$+[1]\n";
  # print "Capture Group 2 is $2 ... and so on\n";
}

# ${^POSTMATCH} and ${^PREMATCH} are also available with the use of '/p'
# Named capture groups can be called via $+{name}

RegEx电路

jex.im可视化正则表达式:

enter image description here