我无法获得正在寻找的正则表达式和嵌套项目的结果

时间:2013-09-06 21:21:03

标签: php regex

我正在研究一些正则表达式,以隔离括号中的代码......

Regex: /\[(.*?)\]/

String: "<strong>[name]</strong>
<a href="http://www.example.com/place/[id]/">For more info...</a>"

Matched Fields: name, id

我希望让它更先进一点。我想做什么......

String: "[if:name <strong>[name]</strong>]
<a href="http://www.example.com/place/[id]/">For more info...</a>"

Matched Fields: if:name <strong>[name]</strong>, id

问题是,我无法弄清楚任何正确的正则表达式。我很确定我已经杀了一天中最好的一半了,我觉得我非常接近。

这就是我现在所做的不是我想要的......

/\[([^\]]+)\]/

有人有什么想法吗?

4 个答案:

答案 0 :(得分:2)

PHP支持递归语法(如(?R)),因此您可以使用此正则表达式:

\[((?:[^\[\]]+|(?R))+)\]

regex101 demo

结果为:if:name <strong>[name]</strong>id

(?R)是整个正则表达式的重复,因此是“递归的”。其他字符应该很容易理解,如果没有,regex101提供了正则表达式组件的全面描述:)

答案 1 :(得分:0)

而不是使用正则表达式来处理html等,它更容易解析文件。不确定你使用的语言是什么,所以我将给出一个Java解析器的例子。 JSoup允许您使用CSS选择器访问文档。让事情变得如此简单!看看教程等,看看是否更容易。

正则表达式很好而且强大不要误解我,但试试解析器。

答案 2 :(得分:0)

答案 3 :(得分:0)

如果您只想要平衡括号和/或递归内部括号的核心,这可能会有所帮助。可以完成许多嵌套级别。这只是一个可能更复杂的使用的框架。平衡的文本部分实际上更容易。

 # (?:(?>[^\\\[\]]+|(?:\\[\S\s])+)|(?>\[((?:(?&core)|))\]())|([\[\]])())(?:\2|\4)(?(DEFINE)(?<core>(?>[^\\\[\]]++|(?:\\[\S\s])++|\[(?:(?&core)|)\])+))

 (?:
      (?>
           [^\\\[\]]+ 
        |  
           (?: \\ [\S\s] )+
      )
   |  
      (?>
           \[
           (                       # (1) core content
                (?:
                     (?&core) 
                  |  
                )
           )
           \]
           ( )                     # (2) core flag
      )
   |  
      # unbalanced '[' or ']'
      ( [\[\]] )                   # (3) error content
      ( )                          # (4) error flag
 )

 (?: \2 | \4 )            # only let match if core flag or error flag is set
                          # this filters search to square brackets only
 (?(DEFINE)
      # core
      (?<core>
           (?>
                [^\\\[\]]++ 
             |  
                (?: \\ [\S\s] )++
             |  
                \[
                # recurse core
                (?:
                     (?&core) 
                  |  
                )
                \]
           )+
      )
 )


 # Perl sample, but regex should be valid in php
 # ----------------------------
 # use strict;
 # use warnings;
 # 
 # 
 # $/ = "";
 # 
 # my $data = <DATA> ;
 # 
 # parse( $data ) ;
 # 
 # 
 # sub parse
 # {
 #      my( $str ) = @_;
 #      while 
 #      (
 #           $ str =~ /
 #               (?:(?>[^\\\[\]]+|(?:\\[\S\s])+)|(?>\[((?:(?&core)|))\]())|([\[\]])())(?:\2|\4)(?(DEFINE)(?<core>(?>[^\\\[\]]++|(?:\\[\S\s])++|\[(?:(?&core)|)\])+))
 #           /xg 
 #      )
 #      
 #      {
 #           if ( defined $1 )
 #           {
 #                print "found core \[$1\] \n";
 #                parse( $1 ) ;
 #           }
 #           if ( defined $3 )
 #           {
 #                print "unbalanced error '$3' \n";
 #           }
 #           
 #      }     
 # }
 # __DATA__
 # 
 # this [ [ is a test
 # [ outter [ inner ] ]