Regex 如何在Perl中使用正则表达式中的分词、星号和分词?
我有一个Perl中的complexe预编译正则表达式。在大多数情况下,正则表达式很好,它匹配所有它应该匹配的内容,而不匹配任何内容。除了一点 基本上,我的正则表达式看起来像:Regex 如何在Perl中使用正则表达式中的分词、星号和分词?,regex,perl,Regex,Perl,我有一个Perl中的complexe预编译正则表达式。在大多数情况下,正则表达式很好,它匹配所有它应该匹配的内容,而不匹配任何内容。除了一点 基本上,我的正则表达式看起来像: my $regexp = qr/\b(FOO|BAR|\*)\b/; 不幸的是,m/\b\*\b/与示例*不匹配。只有m/\*/可以执行由于误报而无法使用的操作。有什么解决办法吗 从评论中可以看出,误报有:**,示例*,检查*ple 正则表达式的用途是什么它应该提取同事在产品数据中输入的关键字(一个是单个星号)。目标是将
my $regexp = qr/\b(FOO|BAR|\*)\b/;
不幸的是,m/\b\*\b/
与示例*
不匹配。只有m/\*/
可以执行由于误报而无法使用的操作。有什么解决办法吗
从评论中可以看出,误报有:**
,示例*
,检查*ple
正则表达式的用途是什么它应该提取同事在产品数据中输入的关键字(一个是单个星号)。目标是将此信息从自由文本字段移到原子字段。如何:
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*
听起来你想把
*
当作一个单词字符
\b
相当于
(?x: (?<!\w)(?=\w) | (?<=\w)(?!\w) )
(?x:(?)?
所以你想要
(?x: (?<![\w*])(?=[\w*]) | (?<=[\w*])(?![\w*]) )
(?x:(?)?
应用后,您将获得以下结果:
qr/
(?: (?<![\w*])(?=[\w*]) | (?<=[\w*])(?![\w*]) )
(FOO|BAR|\*)
(?: (?<![\w*])(?=[\w*]) | (?<=[\w*])(?![\w*]) )
/x
qr/(?<![\w*])(FOO|BAR|\*)(?![\w*])/
qr/
(?: (?
但考虑到我们对中间表达式的了解,可以简化为:
qr/
(?: (?<![\w*])(?=[\w*]) | (?<=[\w*])(?![\w*]) )
(FOO|BAR|\*)
(?: (?<![\w*])(?=[\w*]) | (?<=[\w*])(?![\w*]) )
/x
qr/(?<![\w*])(FOO|BAR|\*)(?![\w*])/
<代码> QR/(?< P>)问题是Perl不认为<代码> *>代码>是“单词字符”,因此不识别空间和星号之间的单词边界(而它在<<代码> r>代码>和<代码> */<代码> <代码> foabar */COD>之间识别。
解决方案是首先决定你要考虑的是“Word”和“NoWord”字符,然后明确地检查它。例如,如果你希望你的单词只包含字母“a”到“z”(或者它们的小写版本)和<代码> */Cube >,并且对于所有被当作非单词字符的词,你可以使用:
/(?<![A-Za-z*])(FOO|BAR|\*)(?![A-Za-z*])/
它将匹配FOO
、BAR
或*
,前提是它们前面或后面没有非空白字符。在*
之前和之后允许哪些字符?所有分词字符,如SOL(行首),EOL,空白,非a-z 0-9。\b
最精细的\b
是单词字符和非单词字符之间的边界。*
和空格之间没有单词边界。*
会遇到什么误报?regexp到底应该匹配什么?看起来你想将*
视为一个普通的单词字符。但它不是,所以\b
不会像您期望的那样工作。请记住\b
根本不匹配任何字符-它匹配不同类别字符之间的零宽度边界(\w
和非\w
)不幸的是,它也匹配了所有的假阳性,看起来komodo已经挂断了,请注意使用[A-Za-z*]
会更改FOOÉ的结果。请注意,使用\S
会更改FOO的结果。
\b