簡體   English   中英

正則表達式,帶有preg_match_all的模式中的反向引用問題

[英]regex, problem with backreference in pattern with preg_match_all

我想知道這里的反向引用有什么問題:

preg_match_all('/__\((\'|")([^\1]+)\1/', "__('match this') . 'not this'", $matches);

它應該匹配__('')之間的字符串,但實際上它返回:

match this') . 'not this

有任何想法嗎?

您不能在字符類中使用反向引用,因為字符類只匹配一個字符,反向引用可能匹配任意數量的字符,或者沒有。

你要做的是需要一個負面的預測,而不是一個否定的角色類:

preg_match_all('/__\(([\'"])(?:(?!\1).)+\1\)/',
    "__('match this') . 'not this'", $matches);

我也改變了你的交替 - \\'|" - 改為一個字符類 - [\\'"] - 因為它更有效率,我逃脫了外括號,使它們與字面括號匹配。


編輯:我想我需要擴展“更有效”的評論。 我接過例如弗里德爾用來證明這一點,並在使用RegexBuddy測試它。

應用於目標文本abababdedfg
^[ag]+$在三個步驟后報告成功,而
^(?:a|b|c|d|e|f|g)+$需要55步。

這是一場成功的比賽。 當我在abababdedfz上嘗試時,
^[ag]+$報告21步后失敗;
^(?:a|b|c|d|e|f|g)+$需要99步。

在這種特殊情況下,對性能的影響是微不足道的,甚至不值得一提。 我只是說,無論何時你發現自己在一個字符類和一個兩個都匹配相同的事物的選擇之間做出選擇,你幾乎總是應該選擇角色類。 只是一個經驗法則。

我很驚訝它沒有給你一個不平衡的括號錯誤信息。

 /
   __
   (
       (\'|")
       ([^\1]+)
       \1
 /

[^\\1]不會獲取捕獲緩沖區1的內容並將其放入字符中
類。 它與所有不是'1'的字符相同。

嘗試這個:

/__\\(('|").*?\\1\\).*/

您可以添加內部捕獲括號,以捕獲引號之間的內容:
/__\\(('|")(.*?)\\1\\).*/

編輯:如果不允許內部分隔符,請使用Qtax正則表達式。
因為, ('|").*?\\1即使不貪婪,仍將匹配所有尾隨錨。在這種情況下__('all'this'will"match') ,並且它更好用('[^']*'|"[^"]*) as

你可以使用類似的東西: /__\\(("[^"]+"|'[^']+')\\)/

讓你的正則表達不合適:

preg_match_all('/__((\'|")([^\1]+)\1/U', "__('match this') . 'not this'", $matches)

暫無
暫無

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

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