“#(\w+)=([\'"])(.*)\\2#U”是什么意思?

4

我是一个正则表达式的新手。

我希望有人能解释一下 #(\w+)=([\'"])(.*)\2#U 这段代码的含义。

preg_match_all('#(\w+)=([\'"])(.*)\\2#U', $str, $matches);

提前致谢。


2
我推荐使用Expresso: http://www.ultrapico.com/Expresso.htm - Dave Swersky
我会添加这个链接: http://www.regular-expressions.info/ - FrustratedWithFormsDesigner
@Dave:Expresso 很棒,但最好用于 .NET 模式。我认为 OP 正在使用 PHP,不确定是否有任何主要差异。 - FrustratedWithFormsDesigner
4个回答

8
让我们逐个解析它。首先,注意到 preg_match_all 在正则表达式周围有定界符,所以 # 不匹配任何内容,但是 U 很重要:它是一个使匹配 "不贪心" 的修饰符。这意味着与其尽可能匹配,所有的量词(?*+{,})都会尽可能少地匹配。然后,逐个解释:
  1. (\w+)\w 匹配“单词字符”——字母数字或下划线;+ 匹配一个或多个这样的字符;圆括号将其分组并将其存储在第一个捕获组中,可以使用 \1 访问该组。
  2. =:匹配文字 =。非常简单 :)
  3. ([\'"]):方括号引入了一个字符类,这是一种简写方式,用于表示“匹配其中任何一个字符”。这里,字符类是 ['"],但由于它是一个单引号字符串,因此必须转义 '。因此,这将匹配一个 ' 或一个 ",并将结果存储在第二个捕获组中,可以使用 \2 访问该组。这是此特定正则表达式中唯一相关的捕获组。
  4. (.*):点号匹配任何非换行符字符,* 匹配任意数量(零个或多个)的它们。这就是为什么 U 修饰符很重要!如果没有它,这将一直匹配到行尾;有了它,它将匹配到下一个匹配项。请注意,由于它在括号内,因此它在第三个捕获组中,可以使用 \3 访问该组(令人震惊)。
  5. \\2:如果我们不必转义反斜杠,那么这将只是 \2:第二个捕获组的内容。在这种情况下,它是我们在步骤 3 中匹配的引号之一。

将所有内容综合起来,这个正则表达式大致匹配一个变量名(第一步)后跟着等号(第二步),再跟着一个字符串(第3-5步);\2的原因是为了避免正则表达式匹配到"string',而U修改器的原因是为了使foo="string" bar="strung"返回两个匹配项foo="string"bar="strung"(其中\1foobar\3stringstrung),而不是单个贪婪匹配foo="string" bar="strung"(其中\1foo\3string" bar="strung)。 一些例子如下:

foo_bar_123="John's applesauce."
100='seventeen'
banana_split=""
_="This is a normal string"

这些实体可以散布在字符串中,可以在同一行或不同行上,可以在周围的文本中或不在其中,只要每个实体本身在一行上。请注意,不允许有空格,因此foo = "bar"不会匹配。


@loptr:哇,谢谢。我简直不敢相信那个错误居然存在了将近两年!现在已经修复了。 - Antal Spector-Zabusky

2
您正在匹配以下格式的字符串:
foo='bar'

baz="blat"
(\w+)匹配一个或多个单词字符。 (单词字符是a到z,A到Z和下划线。)
=匹配文字等号。
[\'"]匹配单引号或双引号。
(.*)匹配零个或多个字符序列。
\ 2是转义的\ 2,在regexp中匹配第二次匹配。 在这种情况下,您的第二个匹配项是单引号或双引号。 使用\ 2可以确保匹配引号,并且您可以在字符串中使用其他样式的引号。

1
我将把它分成块。
 #

这将打开正则表达式字符串。

 (\w+)

这个匹配并捕获1个或多个单词字符,包括A到Z的大写和小写字母以及下划线。它遇到等号符号停止。

 =

匹配一个等号符号。

 ([\'"])

匹配并捕获单引号或双引号字符。

 (.*)\\2

匹配并捕获除 \n 外的任何字符,直到 "\2" 的最后一次出现,"\ "仅匹配一个 \ 字符。

 #

这个语句结束了正则表达式字符串。

 U

这是一个匹配字符串的参数,我相信它意味着将其作为UTF-8字符串进行匹配。我对PHP如何处理此事不太熟悉,因此其他人可能更有权威性。

这将捕获3个匹配项并将它们放入一个名为$matches的数组中,按照它们被匹配的顺序排列。

希望这能帮到您。


1

这个正则表达式可能用于获取名称/值对,其中名称由一个或多个单词字符 (\w+) 组成,后跟等号 (=),后跟一个被单引号或双引号包裹的字符串 (['"])。其余部分 ((.*)\2) 仅用于获取引号之间的所有内容,而 \2 确保匹配正确的引号(与第二个 子模式 中匹配的引号相同)。由于使用了 U 修饰符,因此所有 量词 都是勉强的,所以它们只匹配尽可能少的内容。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接