假设我有以下正则表达式:
/BAR|FOO BAR/gi
以及以下输入字符串:“FOO BAR”
我希望在“BAR”上得到匹配,但实际上我在“FOO BAR”上得到匹配。为什么是这样?
假设我有以下正则表达式:
/BAR|FOO BAR/gi
以及以下输入字符串:“FOO BAR”
我希望在“BAR”上得到匹配,但实际上我在“FOO BAR”上得到匹配。为什么是这样?
首先,让我们检查一下您的正则表达式:
"/BAR|FOO BAR/gi"
这搜索的是匹配的字符串BAR
或FOO BAR
匹配的字符串。标志(假设符合perl正则表达式)是“全局”和“不区分大小写”:
让我们尝试一些事情来了解匹配的工作原理(注意:我使用它是perl
因为它是最流行的正则表达式实现,但如果它兼容,这些示例应该适用于您的语言):
use warnings;
use strict;
my $string = "FOO BAR";
if ($string =~ /FOO/) { print "1. True\n"; } # 'FOO' matches in string
if ($string =~ /BAR/) { print "2. True\n"; } # 'BAR' matches in string
if ($string =~ /foo/i) { print "3. True\n"; } # 'foo' matches in string, ignoring case
true
这将为所有 3 个语句 ( demo )打印,证明FOO
,BAR
并且foo
都是与忽略大小写标志的有效匹配。
那么,为什么你的正则表达式匹配' FOO BAR
'而不是' BAR
'?
因为,如文档所述,解析器将尝试匹配字符串中最早的匹配项。
my $string = "FOO BAR";
$string =~ /(FOO BAR|BAR)/;
print $1; # Prints 'FOO BAR'
请注意,设置/g
不会导致两者都匹配,因为它会尝试尽可能/FOO BAR|BAR/
多地匹配整个规则,而不是匹配规则的每一侧。一旦 ' FOO BAR
' 被匹配,它将停止尝试匹配字符串的那部分并继续前进。
如果你想同时匹配FOO BAR
和 ,你会怎么做BAR
?
给定您的输入字符串,此正则表达式将匹配 ' FOO BAR
' 和 ' ':BAR
my $string = "FOO BAR";
$string =~ /(FOO (BAR))/;
print "$1\n"; # Prints 'FOO BAR'
print $2; # Prints 'BAR'
在上下文中展示/g
国旗
这,使用/g
标志,将匹配FOO
和BAR
:
my $string = "FOO BAR";
while($string =~ /(FOO|BAR)/g) {
print "$1\n";
}
此示例将匹配FOO
后跟空格,BAR
并且FOO BAR
适用于任何输入字符串。
my $string = "FOO BAR";
while($string =~ /((FOO\s)?(BAR))/g) {
print "$1\n$2\n$3";
}
注意:我已经从示例中删除了不相关的标志,以免将来的读者与类似问题混淆。
正则表达式从头开始。它看到F
, 并尝试将其与BAR
选项匹配。这当然失败了。然后它会尝试该FOO BAR
选项,这似乎有效,因此它运行该选项以确定它是否有效。果然,它确实如此,所以匹配是FOO BAR
.