2012-06-04 124 views
2

我想這或多或少是一個由兩部分組成的問題,但這裏首先介紹一些基本知識:我寫了一些PHP來使用preg_match_all來查看由{}結尾的字符串變量。然後它遍歷每個返回的字符串,用MySQL查詢中的數據替換它找到的字符串。PCRE正則表達式語法

第一個問題是這樣的:任何好的網站都可以真正瞭解PCRE表達式的來龍去脈嗎?我在谷歌上搜索了很多,但目前爲止我找到的最好的一個是http://www.regular-expressions.info/。在我看來,那裏的信息沒有很好的組織,因爲當我需要寫一個複雜的正則表達式時,我寧願不要求求助,請給我指點幾個站點(或幾本書)!這將幫助我在將來不必打擾您。

第二個問題是這樣的:我有這樣的正則表達式

"/{.*(_){1}(.*(_){1}[a-z]{1}|.*)}/" 

,我需要它趕上如{first_name}, {last_name}, {email}情況下,等我有三個問題,這個正則表達式。

首先它將「{first_name} {last_name}」看作一個字符串,當它看作是兩個字符串時。我已經能夠通過檢查空間的存在來解決這個問題,然後在空間上爆炸。凌亂,但它的作品。

第二個問題是它包含作爲捕獲字符串的一部分的標點符號。所以,如果你有「{first_name} {last_name}」,那麼它返回逗號作爲字符串的一部分。我已經能夠部分解決這個問題,只需使用preg_replace刪除句點,逗號和分號。雖然它適用於這些標點符號,但我的邏輯無法處理感嘆號,問號和其他所有內容。

我對這個正則表達式的第三個問題是它根本沒有看到{email}的實例。

現在,如果可以的話,願意並且有時間給我解決這個問題的方法,謝謝你解決我眼前的問題。然而,即使你可以這樣做,請提供一個lmgfty,它提供了很好的網站作爲參考和/或一本或兩本書,可以提供這方面的良好教育。由於資金緊張,網站會更可取,但如果一本書是解決方案,我會找到錢(假設我的本地圖書館系統無法購買上述量)。

+2

我真的很喜歡[Mastering Regular Expressions](http://www.amazon.com/Mastering-Regular-Expressions-Jeffrey-Friedl/dp/0596528124)一書。這本書裏有更多的東西比你可能使用的還要多。非常徹底。 –

+0

@JonahBishop:這是一本很好的書,但不是很容易理解;) – 0xC0000022L

+0

@ClementSmith:你說它應該看作是兩個,但是你的正則表達式是貪婪的。在正確的地方添加幾個'?':) – 0xC0000022L

回答

4

那時候我發現PHP自己的PCRE語法參考相當不錯:http://uk.php.net/manual/en/reference.pcre.pattern.syntax.php

讓我們來談談你的表情。它比必要的更冗長得多;我會在簡化它的過程中進行簡化。

一個比較簡單的方式來看看你想要匹配什麼:「找到{,然後任意數量的字母或下劃線,然後}」。這是一個正則表達式(在PHP的string-y語法中):'/\{[a-z_]+\}/'

這將匹配您的所有示例,但也可以匹配一些像{__a_b}這樣的更加狂野的示例。如果這不是一個選項,我們可以用一個更復雜的描述:「找到一個{,然後是一串字母,然後(儘可能多)下劃線後跟一堆字母,然後是一個}」。在正則表達式中:/\{([a-z]+(_[a-z]+)*\}/

第二個可能需要更多解釋。由於我們想重複與_foo段相匹配的內容,因此我們需要將它放在括號內。然後我們說:試着儘可能多地找到它,但如果你根本找不到它(這就是*的含義)。

  • 你表達{}內的任何字符,包括}{和一大堆的匹配:

    所以,現在我們有一些你嘗試比較,讓我們來看看是什麼原因導致你的問題

    其他事情。換句話說,{abcde{_fgh}將被您的正則表達式接受,{abcde} fg_h {ijkl}也會被接受。

  • 你已經有了一個強制性的_在那裏,緊接在第一個.*之後。 (_){1}(意思與_完全相同)表示:無論發生什麼,如果不在這裏,會發生爆炸!很明顯,你實際上並不想這樣做,因爲它永遠不會匹配{email}

這裏是在你的正則表達式匹配什麼通俗的語言的完整描述:

  1. 匹配一個{
  2. 匹配_
  3. 只要你能匹配所有剩下的規則,就可以匹配任何東西。
  4. 匹配_
  5. 匹配一個字母。
  6. 而不是那個_和單個字母,絕對沒有問題。
  7. 匹配}

這可能離你想要的很遠。不過不要擔心。正則表達式需要一段時間才能習慣。我認爲如果你從指令的角度來考慮它,比如建立一個正則表達式,試着在你的腦海中建立一個「找到這個,然後找到它」等等,那麼它是非常有用的。然後找出正確的語法來實現就是這樣。

這很難,主要是因爲並不是所有的指令都可以很容易地轉換成一個正則表達式......但是這就是經驗來的地方。我向你保證,你會把它放在沒有時間......如果你一開始就很有條理地製作正則表達式。

祝你好運! :)

+0

謝謝你。我以前沒有想過以這種方式去思考正則表達式。我想這只是缺乏經驗,真的。我非常感謝您的回覆,並且已預訂此頁面供將來參考。 (我還從圖書館訂購了@JonahBishop建議的書) –

+0

感謝您的鏈接。 :) – jsbisht

1

對於PCRE,我只是消化PCRE手冊頁,但當時我的大腦這樣工作反正...

至於匹配分隔東西,你通常有兩種方式:

  1. 比賽第一個分隔符,匹配任何不是結束分隔符,匹配結束分隔符。
  2. 匹配第一個分隔符,匹配任何不合理,匹配結束分隔符。

例如,對於你的情況:

  1. \{([^}]+)\}
  2. \{(.+?)\} - 注意+

我加了一組圍繞內容你很可能要提取過。

還要注意的是#1的情況下,特別是#2的情況下,如果「點匹配任何東西」有效(dotall,singleline或任何你最喜歡的正則表達式調用它),他們也會匹配linebreaks - 如果這是一個問題,您需要手動排除該問題以及其他任何您不需要的內容;如果您想要更像白名單的方法,請參閱上述答案。

0
  1. 這是good regex site
  2. 這裏有一個PCRE正則表達式,將工作:\{\w+\}

下面是它如何工作的: 它基本上尋找{隨後one ore more word characters其次}。有趣的部分是字符類實際上也包含一個下劃線。 \w基本上是[A-Za-z0-9_]

的簡寫因此它基本上會匹配大括號內的這些字符的任意組合,並且由於加號只會匹配非空的大括號。