正则表达式 。*?和。*

时间:2016-04-02 05:55:09

标签: regex perl

这两个正则表达式有什么作用?

/<(.*?)>.*?<\/\1>/

/<(.*?)>.*<\/\1>/

我所学到的是.*?意味着尽可能少的角色。

例如:

  my $a = '"helllo"++"world"';

  print "a $1\n" if $a =~/(".*")/;            # "helllo"++"world"

  print "b $1\n" if $a =~/(".*?")/;           # "helllo"

  print "c $1\n" if $a =~/(.*)/;              # "helllo"++"world"

  print "d $1\n" if $a =~/(.*?)/;             # (nothing)

为什么d什么都不显示,b是helllo而不是""

所以,我找不到任何好的例子来显示1 and 2helllo world示例之间的区别。

有人可以举一些例子来说明差异吗?

感谢。

4 个答案:

答案 0 :(得分:1)

*表示匹配零次或多次

*?表示匹配零次或多次但不贪心

.表示它匹配除新行

之外的任何字符

'"helllo"++"world"'这是你的骚动

在下面的示例中,^表示当前位置(字符串中有当前位置,模式中有当前位置(种类))

在你的第一个案例中。

步骤1

"helllo"++"world"      ".+"
^                      ^  

第二步

"helllo"++"world"      ".+"
 ^                      ^  

步骤3

"helllo"++"world"      ".+"
                ^        ^

步骤4

由于我们在字符串"回溯的末尾找到.+并匹配"

之前的字符

检查"

We have the match at this position so success

"helllo"++"world"      ".+"
               ^          ^

在你的第二个案例中。 *? Match zero or more times but not greedy

步骤1

  "helllo"++"world"     ".*?"
  ^                     ^  

第二步

  "helllo"++"world"     ".*?"
   ^                     ^  

步骤3

  "helllo"++"world"     ".*?"
         ^                 ^  

Step4(*在第一场比赛满足时失败。)

  "helllo"++"world"     ".*?"
         ^                  ^  

在你的第三种情况下

第1步

"helllo"++"world"        .* 
^                        ^ 

第2步(*贪婪,直到结束。结果是给出所有匹配的模式)

"helllo"++"world"        .* 
                ^         ^ 

在你的第四个案例中,

您的模式为.*?这意味着(.) 或更多次(*),但不是贪婪(?)。这里非贪婪的字符与零字符匹配,因此结果为空。

答案 1 :(得分:1)

.*?将使用尽可能少的字符搜索匹配项。如果您将".*?""a" "b"匹配,则正则表达式引擎将仅报告"a"作为匹配项。贪婪版本".*"会将整个字符串报告为匹配项,因为*希望尽可能多地使用输入。

正则表达式.*?可以满足一个空字符串,所以如果你不在它周围放任何东西,以防止匹配正是它所做的事情(比如你的情况d)。

你的正则表达式1)和2)用于解析看起来像XML的文本。请考虑以下文字:

<tag>text</tag> <tag>more text</tag>

正则表达式1)将仅消耗第一个带标记的子字符串<tag>text</tag>,而正则表达式2消耗整个字符串。

现在考虑一下这个文字:

<tag>what about <tag>nested</tag> tags?</tag>

正则表达式1)只会产生匹配,直到第一个结束</tag>,而正则表达式2)消耗整个字符串。

答案 2 :(得分:1)

你真的有两个问题,一个在这里;

  

这两个正则表达式有什么作用?

     

/≤(?*)&GT。* LT; / \ 1&GT; /

点,&#39;。&#39;,是匹配任何字符的原子。后面的星号表示&#34;尽可能多地匹配前一个原子。&#34;这种组合被称为&#34;贪婪&#34;因为点匹配任何东西和&#39; *&#39;说 - &#34;继续前进&#34;因此,在没有任何其他约束或锚点的情况下,组合使用&#39;吃或匹配字符串的其余部分。问号会改变这种行为来自&#34;贪婪&#34;到&#34;吝啬&#34; - 它会尽可能少地匹配。

圆括号 - 或括号 - 没有规定要匹配的内容 - 它们表示你想要捕获&#34;与名为&#34; $ 1&#34;的特殊变量匹配的任何内容对于第一对括号,&#34; $ 2&#34;对于第二个等等。

所以这个, - <(.*?)>意味着,匹配一个开放的尖括号(或者#34;小于&#34;),然后匹配任何东西(但是尽可能少地占用),然后匹配一个闭合角度(或&#34;大于&#34;)。圆括号没有规定什么匹配 - 它们只是意味着&#34;将尖括号之间的任何文本放入$ 1。&#34;

最后一部分中的\1<\/\1>,被称为后引用 - 它意味着&#34;无论你在第一组圆括号中捕获了什么,我想要再次在这里匹配&#34;。它之前的\/是一个转义正斜杠 - 所以我们在这里寻找的是一个&#34;标签&#34; (由尖括号括起来的文字),一些文字然后匹配的&#34;结束标记&#34; - 即尖括号中的相同文字带有&#39; /&#39;在前面。

  

/≤(?*)&GT。* LT; / \ 1&GT; /

除了尝试在开始标记和结束标记之间尽可能多地使用文本之外,这几乎完全相同。

my $a = '"helllo"++"world"';
...
print "b $1\n" if $a =~/(".*?")/;            # "helllo"
...
print "d $1\n" if $a =~/(.*?)/;
  

为什么d什么都不显示,b是&#34; helllo&#34;不是&#34;&#34;?

用(b),你说&#34;我在开始时坚持双引号(&#34;),然后是任何文字,然后我再次坚持收尾双引号(&#34; )&#34 ;.现在,如果您查看$ a中的文本,您可以看到以下所有内容的开头和结尾(&#34;),其中包含一些文本;

"helllo" 
"helllo"++" 
"helllo"++"world"

这里的主要观点 - .*?(吝啬)意味着&#34;我想要最小的一个&#34; - 即在这种情况下是第一个,而.*(没有&#39;?&#39; - 贪婪)意味着&#34;我想要最长的一个&#34; - 即在这种情况下,最后一个。

使用(d),你没有在字符串的开头或结尾处规定的尖括号或双引号字符 - 你只是说&#34;匹配任何东西,(。*)但尽量少用& #34 ;.因此,RE根本没有给你什么,因为它肯定是满足标准的最小匹配(即没有标准!: - )

答案 3 :(得分:0)

原因d)打印没有什么是非常简单的:你已经知道.*?匹配尽可能少,所以没有添加任何其他标准,“尽可能少”根本就没有。

b)"(.*?)"匹配"hello"的原因是表达式中的两个引号 - 即匹配(如果找到)必须以引号开头和结尾。中间部分.*?匹配尽可能少,所以这是“你好”。