繁体   English   中英

如何使用 Perl 在 Regex 中使用分词、星号、分词?

[英]How to use word break, asterisk, word break in Regex with Perl?

我在 Perl 中有一个复杂的预编译正则表达式。 在大多数情况下,正则表达式很好,可以匹配它应该匹配的所有内容,而没有不应该匹配的内容。 除了一分。

基本上我的正则表达式看起来像:

my $regexp = qr/\b(FOO|BAR|\*)\b/;

不幸的是m/\\b\\*\\b/不会匹配example, * 只有m/\\*/会做,因为误报我不能使用。 有什么解决方法吗?

来自评论 -误报是: ** , example* , example* exam*ple

正则表达式的用途是什么? -它应该提取同事输入产品数据的关键字(一个是单个星号)。 目标是将这些信息从自由文本字段中移到原子字段中。

听起来您想将*视为单词字符。

\b

相当于

(?x: (?<!\w)(?=\w) | (?<=\w)(?!\w) )

所以你要

(?x: (?<![\w*])(?=[\w*]) | (?<=[\w*])(?![\w*]) )

申请后,您将获得以下信息:

qr/
    (?: (?<![\w*])(?=[\w*]) | (?<=[\w*])(?![\w*]) )
    (FOO|BAR|\*)
    (?: (?<![\w*])(?=[\w*]) | (?<=[\w*])(?![\w*]) )
/x

但鉴于我们对中间表达式的了解,可以将其简化为以下内容:

qr/(?<![\w*])(FOO|BAR|\*)(?![\w*])/

问题是 Perl 不认为*是“单词字符”,因此不识别空格和星号之间的单词边界(而它确实识别rfoobar**之间的边界)。

解决的办法是先决定要考虑的“字”,“无字”的字符,然后检查该明确的东西。 例如,如果您希望您的单词由字母 'A' 到 'Z'(或其小写版本)和* ,并且其他所有内容都被视为非单词字符,您可以使用:

/(?<![A-Za-z*])(FOO|BAR|\*)(?![A-Za-z*])/

这将匹配字符串FOOBAR* ,前提是它们前面或后面没有匹配[A-Za-z*]的字符。

同样,如果您想将除空格以外的所有内容都视为非单词字符,您可以使用:

/(?<!\S)(FOO|BAR|\*)(?!\S)/

它将匹配FOOBAR* ,前提是它们前面或后面没有非空白字符。

怎么样:

my $regexp = qr/(?:\b(FOO|BAR)\b)|(?:^| )\*(?:$| )/;

在行动:

my $re = qr~(?:\b(FOO|BAR)\b)|(?:^| )\*(?:$| )~;
while(<DATA>) {
    chomp;
    say (/$re/ ? "OK : $_" : "KO : $_");
}


__DATA__
FOO
BAR
*
exam*ple
example*

输出:

OK : FOO
OK : BAR
OK : *
KO : exam*ple
KO : example*

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM