2011-03-04 80 views
4

我有一些正則表達式運行在整個HTML頁面尋找字符串和替換它們,但是如果字符串是在單引號或雙引號,我不希望它匹配。正則表達式PHP只匹配,如果不包圍行情

當前正則表達式:([a-zA-Z_][a-zA-Z0-9_]*)

我想匹配stevejohncathiejohn likes to walk(X3) 但不"steve"'sophie'"john"'likes'"cake"

我已經試過(^")([a-zA-Z_][a-zA-Z0-9_]*)(^")但沒有得到匹配?

測試用例:

(steve=="john") would return steve 
("test"=="test") would not return anything 
(boob==lol==cake) would return all three 
+0

我在你的正則表達式又看了看,發現'([A-ZA-Z _] [A-ZA-Z0-9_] *)'已經匹配沒有引號... – BoltClock 2011-03-04 17:54:28

+1

@BoltClock問題是,他只希望它匹配時,沒有引號(我認爲)。 – 2011-03-04 17:54:54

+0

這些字符串是一樣嗎?開始/結束是'steve','john'。或者他們是否存在於另一種情況下,比如'史蒂夫和約翰一起散步。約翰說「史蒂夫」。什麼是幾個測試用例? – 2011-03-04 17:56:37

回答

3

試試這個:

(\b(?<!['"])[a-zA-Z_][a-zA-Z_0-9]*\b(?!['"])) 

在此字符串:

 
john "michael" michael 'michael elt0n_john 'elt0n_j0hn' 
1  2  3  4  5   6 

它將匹配nr 1 john,nr 3 Michael和nr 5 elt0n_john

1

要做到這一點,你可能需要一些黑暗魔法:

'~(?:"[^"\\\\]*+(?:\\\\.[^"\\\\]*+)*+"|\'[^\'\\\\]*+(?:\\\\.[^\'\\\\]*+)*+\')(*SKIP)(*F)|([a-zA-Z_][a-zA-Z0-9_]*)~' 

(?:"[^"\\\\]*+(?:\\\\.[^"\\\\]*+)*+"|\'[^\'\\\\]*+(?:\\\\.[^\'\\\\]*+)*+\')部分的字符串匹配單個或雙引號,並實現反斜槓逃逸。 (*SKIP)(*F)跳過引用的字符串並強制失敗。 ([a-zA-Z_][a-zA-Z0-9_]*)是你的正則表達式。 PS:如果您在PHP腳本上使用此腳本,則可能需要使用Tokenizer。這樣,你可以例如排除關鍵字(如classabstract,我不知道你是否需要這個),並且你會更好地處理邊緣案例(如HEREDOC)。

2

你可以嘗試用:

preg_match_all('#(?<!["\']) \b \w+ \b (?!["\'])#x', $str, $matches); 

\w+匹配單詞字符,但允許0123sophie例如。 \b匹配單詞邊界,從而確保反引號聲明不會過早終止。

然而,這正則表達式也將無法找到它之前或之後」他們剛纔一個單引號」字樣

+0

經過測試,並在正則表達式教程中很好...雖然在PHP中失敗,但不知道爲什麼。 http://codepad.org/LEitQoEJ可能只是鍵盤的問題。 – 2011-03-04 18:13:01

+0

也一樣。使用我在codpad中發佈的測試用例,我在PHP CLI中嘗試過。它很好用,並返回一個包含'but','john','like','apples'的數組 – 2011-03-04 18:21:22

0

好吧,我想我有它,它適用於你的測試用例:

完成與前瞻/向後看的正則表達式功能
 
(?<!"|'|\w)(\w+)(?!"|'|\w) 

1

佩斯,復活這個古老的問題,因爲目前的答案是不完全正確的(我不知道任何解決方案可以)。

它將無法匹配john當它是不完整的報價,例如在"johnjohn"'johnjohn'(情況可以與john's birthday等情況的發生見this demo

這個替代的解決方案只是跳過引號中的任何內容:

(?:'[^'\n]*'|"[^"\n]*")(*SKIP)(*F)|\b[a-zA-Z_][a-zA-Z_0-9]*\b 

demo

無論哪種方式,帶引號的,沒有解決方案是完美的,因爲你總是冒不平衡報價的風險。在這種情況下,我試圖通過假設它在另一行上,這是一個不同的字符串來緩解這個問題。

參考

  1. How to match pattern except in situations s1, s2, s3
  2. How to match a pattern unless...