我很難理解\G
anchor如何在PHP風格的正則表達式中工作。正則表達式中' G'錨的用法是什麼?
在發生相同字符串的多個匹配的情況下,我傾向於使用\G
代替^
(儘管我可能錯了)。
有人可以請示例\G
應該如何使用,並解釋如何和爲什麼它的作品?
我很難理解\G
anchor如何在PHP風格的正則表達式中工作。正則表達式中' G'錨的用法是什麼?
在發生相同字符串的多個匹配的情況下,我傾向於使用\G
代替^
(儘管我可能錯了)。
有人可以請示例\G
應該如何使用,並解釋如何和爲什麼它的作品?
UPDATE
\ G變迫使模式只返回匹配是的連續鏈的一部分匹配。從第一場比賽開始,每場隨後的比賽都必須進行比賽。如果你打破了連鎖,比賽結束。
<?php
$pattern = '#(match),#';
$subject = "match,match,match,match,not-match,match";
preg_match_all($pattern, $subject, $matches);
//Will output match 5 times because it skips over not-match
foreach ($matches[1] as $match) {
echo $match . '<br />';
}
echo '<br />';
$pattern = '#(\Gmatch),#';
$subject = "match,match,match,match,not-match,match";
preg_match_all($pattern, $subject, $matches);
//Will only output match 4 times because at not-match the chain is broken
foreach ($matches[1] as $match) {
echo $match . '<br />';
}
?>
這是直接從文檔
第四使用反斜線的是對於某些簡單的斷言。一個 斷言指定了一個條件,必須在特定的匹配點 處滿足條件,而不消耗來自主題 字符串的任何字符。子模式用於更復雜的斷言是 下面描述。反斜線的斷言是僅在當前匹配位置是 比賽的開始點
\G
first matching position in subject
的\ G斷言,是真實的,如通過 的preg_match()的偏移量參數指定。當偏移值不爲零時,它與\ A不同。
http://www.php.net/manual/en/regexp.reference.escape.php
你將不得不那一頁滾動一點,但它是。
在ruby中有一個很好的例子,但它在php中是一樣的。
謝謝@Jrod,這對我來說是一個正確的方向,我感謝您發佈鏈接到文檔。不幸的是,對於PHP和一般編程來說相對較新,我並沒有從文檔中掌握文檔的實際意義。這就是爲什麼我要求一個例子。 – 2013-02-15 15:56:53
@DimitriVorontzov我添加了一個簡單的例子。我希望這更清楚。 – Jrod 2013-02-15 17:03:09
這真是太棒了,非常感謝你@Jrod! – 2013-02-15 17:06:09
\G
將匹配匹配的邊界,這是字符串的任一開頭,或在最後一場比賽的最後一個字符被消耗點。
當您需要執行復雜的標記,同時還要確保標記有效時,它特別有用。
例問題
讓我們標記化該輸入的例子:
input 'some input in quote' more input '\'escaped quote\'' [email protected]_$of_fun ' \' \\ ' crazy'stuff'
進入這些令牌(I使用~
來表示字符串的結束):
input~
some input in quote~
more~
input~
'escaped quote'~
[email protected]_$of_fun~
' \ ~
crazy~
stuff~
該字符串由以下組合組成:
\
和'
,並且空格被保留。空字符串可以使用單引號字符串指定。\
或'
。爲了簡單起見,我們假設輸入不包含新線(在現實情況下,你需要到考慮)。它會增加正則表達式的複雜性,而不會顯示出重點。
爲單引號的字符串的RAW正則表達式是'(?:[^\\']|\\[\\'])*+'
而對於未加引號的RAW正則表達式是[^\s'\\]++
你不必太在意了2件以上的正則表達式,雖然。
下面\G
該解決方案可以確保當發動機未能找到任何匹配,從字符串到最後一個匹配的位置開始所有字符已被消耗。由於它不能跳過字符,因此當它無法爲兩個標記的規範找到有效的匹配時,引擎將停止匹配,而不是在字符串的其餘部分中抓取隨機的東西。
建設
在建設的第一步,我們可以放在一起這個表達式:
\G(?:'((?:[^\\']|\\[\\'])*+)'|([^\s'\\]++))
或者簡單地說(這是不正則表達式 - 這只是爲了更容易閱讀):
\G(Singly_quote_regex|Unquoted_regex)
這將僅匹配第一個標記,因爲當它嘗試在第二次比賽時,比賽在'some input...
之前停止。
我們只需要添加一些允許0或更多的空間,因此,在隨後的比賽,該位置的剩餘空間關閉的最後一場比賽中被消耗:
\G *+(?:'((?:[^\\']|\\[\\'])*+)'|([^\s'\\]++))
上面的正則表達式現在可以正確識別令牌,如看到here。
正則表達式可以進一步修改,使得它在發動機無法獲取任何有效的標記返回字符串的其餘部分:
\G *+(?:'((?:[^\\']|\\[\\'])*+)'|([^\s'\\]++)|((?s).+$))
由於交替是爲了從左到試-right,當且僅當前面的字符串不構成有效的單引號或不引號標記時,最後一個替代((?s).+$)
纔會匹配。這可以用來檢查錯誤。
第一個捕獲組將包含單引號字符內的文本,需要額外的處理變成所需的文本這(它是不是真的與此有關,所以我把它作爲一個練習的讀者)。第二個捕獲組將包含未加引號的字符串。第三個捕獲組作爲輸入字符串無效的指示器。
結論
上面的例子是在標記化的\G
使用的一個場景的演示。還有其他的用法我沒有遇到過。
謝謝!這個例子非常複雜,讓我分析一下。 – 2013-02-15 17:07:24
@DimitriVorontzov:這更像是一種近乎真實的使用情況,所以它非常複雜。 – nhahtdh 2013-02-15 17:13:11
是的,我明白,@ nhahtdh! – 2013-02-15 17:23:57
請看一個真實的例子這個答案:http://stackoverflow.com/a/2248130/1606729 – koopajah 2013-02-15 15:35:04
@koopajah - 謝謝你。不幸的是,這不是一個恰當的例子。我在問使用\ G錨;您鏈接的示例使用\ g作爲反向引用。 – 2013-02-15 15:38:44
再次感謝@koopajah。新的例子確實使用了\ G,但是從這個例子中,我仍然無法理解任何有關\ G應該如何使用和爲什麼使用的內容。我唯一看到的是\ G在那裏被使用,但爲什麼它被使用,在其他什麼情況下它應該被使用,等等 - 我不明白這一點。請更多的例子? – 2013-02-15 15:42:48