regex - 为什么这个正则表达式匹配第二项而不是第一项

标签 regex

假设我有以下正则表达式:

/BAR|FOO BAR/gi

以及以下输入字符串:“FOO BAR”

我希望在“BAR”上获得匹配,但我实际上在“FOO BAR”上获得匹配。这是为什么?

最佳答案

正则表达式将首先查找匹配的模式

首先,让我们检查一下您的正则表达式:

"/BAR|FOO BAR/gi"

这搜索的是匹配字符串中的 BARFOO BAR。标志(假设 符合正则表达式)是“全局的”和“不区分大小写的”:

  1. Global 标志意味着表达式将尝试返回 all matches in the haystack .
  2. Case insensitive 标志表示无论大小写都会匹配表达式。

让我们尝试一些事情以了解匹配的工作原理(注意:我使用 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

这将为所有 3 个语句 ( demo ) 打印 true,证明 FOOBARfoo 都是带有忽略大小写标志的有效匹配项。

那么,为什么您的正则表达式匹配“FOO BAR”而不是“BAR”?

因为,如文档所述,解析器将 try to match the earliest match in the string .

my $string = "FOO BAR";

$string =~ /(FOO BAR|BAR)/;
print $1; # Prints 'FOO BAR'

请注意,设置 /g 不会导致两者匹配,因为它会尽可能多次尝试匹配 ENTIRE 规则 /FOO BAR|BAR/,而不是匹配规则的每一侧。一旦“FOO BAR”匹配,它将停止尝试匹配字符串的那部分并继续。

如果你想同时匹配 FOO BARBAR,你会怎么做?

This regular expression将匹配 'FOO BAR' 和 'BAR' 给定您的输入字符串:

my $string = "FOO BAR";

$string =~ /(FOO (BAR))/;
print "$1\n"; # Prints 'FOO BAR'
print $2;     # Prints 'BAR'

上下文中/g标志的演示

This ,使用 /g 标志,将匹配 FOOBAR:

my $string = "FOO BAR";

while($string =~ /(FOO|BAR)/g) {
    print "$1\n";
}

匹配您要查找的内容...

This example将匹配 FOO 后跟空格、BARFOO BAR 用于任何输入字符串。

my $string = "FOO BAR";

while($string =~ /((FOO\s)?(BAR))/g) {
    print "$1\n$2\n$3";
}

注意:我已经从示例中删除了不相关的标志,以免将来的读者因类似问题而感到困惑。

关于regex - 为什么这个正则表达式匹配第二项而不是第一项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18382965/

相关文章:

javascript - 从字符串 : 'matrix(1, 0, 0, 1, 3, 5)' 中获取最后 2 个数字

regex - 正则表达式匹配不被括号包围的下划线?

javascript - 如何以编程方式让字符串的所有 unicode 实体自行解析?

regex - 匹配除字符之外的任何内容,除非它后面跟着其他字符

regex - 使用带有 bash 或命令行的正则表达式从文本文件中提取电子邮件地址

java - 如何检测输入的csv文件是否嵌入了引号?

java - 什么是用空格替换所有 "System.out.println()"的正则表达式?

java - 正则表达式匹配任何合法的java函数声明的格式

php - 从 YouTube API 标题标签的开头删除前 24 个字符

javascript - 正则表达式:拆分字符