簡體   English   中英

正則表達式匹配方括號后跟括號,其中方括號也可以包含其他方括號

[英]Regex matching square brackets followed by parenthesis where the square brackets can also contain other square brackets

我有一些像這樣的文本,它是以自定義降價格式編寫的。 例如:

[Lorem ipsum] 
Dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. 

[Ut wisi] 
[Enim ad minim veniam](a), quis nostrud exerci tation ullamcorper. 
suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat. 
Vel illum dolore eu feugiat nulla facilisis at vero.
[Ros et accumsan et iusto odio dignissim](b) qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. 

[[Nam liber]](c)
Tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum.

正如你所看到的那樣,有方括號的方括號,並且有方括號后跟括號括起來,這是我試圖與正則表達式匹配的字母。 我試圖使用的正則表達式是這樣的:

preg_match_all("#\[(.*?)\]\(([a-z]+)\)#is",$html,$matches)

這個問題是從[Lorem ipsum]到(a)的結尾匹配。

我也可以使用以下內容,但是我需要能夠在方括號中包含標題,這樣才能正常工作:

preg_match_all("#\[([^]]+)\]\(([a-z]+)\)#is",$html,$matches)

經過一些閱讀后,我懷疑我需要的是一個前瞻,但是我無法理解他們。 任何幫助非常感謝。


澄清

我基本上希望能夠使用方括號/括號組合來包裝某些文本的任何部分,然后能夠將它們與正則表達式匹配,而不會在任何地方引起沖突。 示例文字:

[[Lorem ipsum]](a)
Dolor sit amet, [consectetuer adipiscing elit](b), sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. 

期望的比賽:

[[Lorem ipsum]](a)
[consectetuer adipiscing elit](b)

或者......更復雜

[[Lorem ipsum]
Dolor sit amet, sed diam nonummy nibh euismod](a) tincidunt ut laoreet dolore magna aliquam erat volutpat. 

期望的比賽:

[[Lorem ipsum]
Dolor sit amet, sed diam nonummy nibh euismod](a)

可能嗎?

干得好。

preg_match_all("~
    \[(              # open outer square brackets and capturing group
    (?:              # open subpattern for optional inner square brackets
        [^[\]]*      # non-square-bracket characters
        \[           # open inner square bracket
        [^[\]]*      # non-square-bracket characters
        ]            # close inner square bracket
    )*               # end subpattern and repeat it 0 or more times
    [^[\]]*          # non-square-bracket characters
    )]               # end capturing group and outer square brackets
    (?:              # open subpattern for optional parentheses
        \((          # open parentheses and capturing group
        [a-z]+       # letters
        )\)          # close capturing group and parentheses
    )?               # end subpattern and make it optional
    ~isx",
    $input,
    $matches);

和正則表達式在一行:

"~\[((?:[^[\]]*\[[^[\]]*])*[^[\]]*)](?:\(([a-z]+)\))?~isx"

工作演示

m.buettner的答案很棒。 它既准確又記錄良好(它得到了我的投票,值得繼續選擇答案)。 我真的很喜歡正則表達式在自由間隔模式下自我記錄的事實。 但是,為了完整起見,(並且作為另一種評論風格的演示)這里是一個等效(但稍微更有效)的正則表達式解決方案:

preg_match_all('/
    # Match a "[...[...]...[...]...](...)" structure.
    \[               # Literal open square bracket.
    (                # $1: Square bracket contents.
      [^[\]]*        # {normal*} Zero or more non-[].
      (?:            # Begin {(special normal*)*}.
        \[[^[\]]*\]  # {special} Nested matching [] pair.
        [^[\]]*      # More {normal*} Zero or more non-[].
      )*             # End {(special normal*)*}.
    )                # $1: Square bracket contents.
    \]               # Literal close square bracket.
    (?:              # Optional matching parentheses.
      \(             # Literal open parentheses.
      ([A-Za-z]+)    # $2: Parentheses contents.
      \)             # Literal close parentheses.
    )?               # Optional matching parentheses.
    /x',
    $input,
    $matches);

改進(主要是化妝品/風格):

  • 正則表達式包含在'single quotes'而不是"double quotes" 對於PHP,使用雙引號字符串有一個額外的解釋級別,還有更多的字符轉義序列需要處理(特別是"$"字符會導致惡作劇)。 底線:使用PHP,最好將單調引號模式包含在單引號字符串中(即減少反斜杠湯 )。
  • [nested [square bracket] structure]匹配的表達式邏輯被重新安排,以實現Friedl的 “展開循環”效率技術。 對於外方括號沒有嵌套方括號的情況,這導致較少的回溯。
  • 捕獲組的開括號和近括號(跨越多行)縮進到相同的級別(即垂直對齊)以便於視覺匹配。
  • 捕獲組編號包含在帶有開括號和閉括號的行的注釋中。
  • s 單行修改被刪除(無需-有沒有點!)。
  • 刪除i ignore case修飾符,並將受影響的字符類[az]更改為[A-Za-z]以進行補償。 (在區分大小寫模式下,某些正則表達式引擎運行得更快。)
  • 文字"]"關閉方括號元字符顯式轉義,即: "\\]" (雖然這不是必需的,但這是恕我直言的好習慣)。
  • 捕獲組$2合並到一行。
  • 在正則表達式的頂部添加了一個全寬標題注釋,用於描述整體正則表達式的目的。

我想你只需稍微調整你的第一個正則表達式:

preg_match_all("#\[(.*?)\](?:\(([a-z]+)\))?#is",$html,$matches)
                          ^^^            ^^

這樣,帶括號的字母是可選的。

編輯:

鑒於澄清,這是一個新的正則表達式:

\[((?:[^][]|\[[^][]*?\])*?\](?:\(([a-z]+)\))?

這是一個Rubular演示

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM