【问题标题】:Regex to match only innermost delimited sequence正则表达式仅匹配最里面的分隔序列
【发布时间】:2011-10-22 20:57:55
【问题描述】:

我有一个字符串,其中包含由多个字符分隔的序列:<<>>。我需要一个正则表达式来只给我 innermost 序列。我已经尝试过前瞻,但它们似乎没有按我期望的方式工作。

这是一个测试字符串:

'do not match this <<but match this>> not this <<BUT NOT THIS <<this too>> IT HAS CHILDREN>> <<and <also> this>>'

它应该返回:

but match this
this too
and <also> this

正如您在第三个结果中看到的那样,我不能只使用/&lt;&lt;[^&gt;]+&gt;&gt;/,因为字符串可能有一个分隔符字符,但不能连续两个。

我刚从试错中解脱出来。在我看来这不应该这么复杂。

【问题讨论】:

  • 理论上,这类问题(堆栈式,取决于某些中间状态等)需要比常规语法更具表现力。
  • 正则表达式只能解析正则文法。这不是常规语法。
  • Perl 的正则表达式根本不是正则的,可以很好地解析。
  • @miku, @cdhowie:因为他想要内括号而不是外括号,所以实际上有一个规则的语法。 /&lt;&lt;(?:[^&lt;&gt;]+|&lt;[^&lt;]|&gt;[^&gt;])*&gt;&gt;/
  • @ikegami:比这更复杂;不匹配所有&lt;&lt;&lt;&gt;&gt;

标签: regex perl delimiter lookahead


【解决方案1】:
@matches = $string =~ /(<<(?:(?!<<|>>).)*>>)/g;

(?:(?!PAT).)* 是模式,就像[^CHAR]* 是字符。

【讨论】:

    【解决方案2】:

    这是一种使用split 完成工作的方法:

    my $str = 'do not match this <<but match this>> not this <<BUT NOT THIS <<this too>> IT HAS CHILDREN>> <<and <also> this>>';
    my @a = split /(?=<<)/, $str;
    @a = map { split /(?<=>>)/, $_ } @a;
    
    my @match = grep { /^<<.*?>>$/ } @a;
    

    将标签保留在其中,如果您想删除它们,只需:

    @match = map { s/^<<//; s/>>$//; $_ } @match;
    

    【讨论】:

      【解决方案3】:
      $string = 'do not match this <<but match this>> not this <<BUT NOT THIS <<this too>> IT HAS CHILDREN>> <<and <also> this>>';
      @matches = $string =~ /(<<(?:[^<>]+|<(?!<)|>(?!>))*>>)/g;
      

      【讨论】:

      • Yessss...我知道有办法。你赢得了 Perl PGA 巡回赛,我的朋友。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-20
      • 1970-01-01
      • 2021-05-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多