2011-09-20 74 views
0

我寫的正則表達式應該做到以下幾點:忽略第二場比賽中的HTML如果不匹配

== Text == 
Other text 
==  Text== 

變爲

<h2>Text</h2> 
<p>Other text</p> 
<h2>Text</h2> 

我幾乎沒有,問題是,這是我目前得到的:

<h2>Text</h2> 
<p>Other text</p> 
<h2>Text</h2> 
<p></p> 

儘管不太可能標題後面沒有文字,但我想修復它至少爲了學習的目的。

這裏是我的功能:

preg_replace('/== *(.*?) *==([^=]*)/m', 
      '<h2>$1</h2> 
       <p>$2</p> 
      ', '== Text == 
       Other text 
       ==  Text=='); 

所以基本上,我想忽略<p></p>的一部分,如果$2是空的。

任何其他提示/改進的歡迎,我想學:)

+0

您應該取消此正則表達式並逐行解析輸入。會阻止你以後發瘋。 – Jon

+0

當然,但爲什麼? :) – Kokos

+0

因爲如果你以後想添加更多的選項,你將無法做到。 – Jon

回答

1

你需要一個簡單的條件,以防止空<p>標籤出現。雖然我不建議這通常,插入最簡單的方法這種簡單的if是使用/e正則表達式修飾符preg_replace

preg_replace('/== *(.*?) *==([^=]*)/me', 
      '"<h2>$1</h2>".(trim("$2") == ""?"":"<p>$2</p>")', 
      '== Text == 
       Other text 
       ==  Text=='); 

這個修改使得替換字符串進行替換之前的PHP代碼進行計算的,所以你可以很容易地適應一個小條件。

See it in action

另一種選擇是使用preg_replace_callback,它實際上是相同的想法,只不過現在您將代碼編寫爲單獨的函數。這是更好的恕我直言,因爲它使代碼更清晰。作爲最後一點,如果您打算添加更多格式化選項,您可能需要考慮將您的分析分解爲多個步驟,並且可能一次處理一行,因爲正則表達式不是用來處理這種處理的。你可以強迫它達到某一點,但它很快就會變得非常難以維持。

+0

這是一個很好的修飾符,我肯定會考慮'preg_replace_callback'因爲你提供的原因,不希望我的PHP代碼在一個函數內突出顯示爲一個字符串。 – Kokos

+0

另一個問題是,如果正則表達式不是爲這種處理設計的,還有更好的方法嗎?或者你的意思是我應該小心我走多遠。據我所知BBCode和變體幾乎在每個論壇(和本網站)上使用,並且這些都是用正則表達式編寫的嗎? – Kokos

+1

@Kokos:對,但他們不會嘗試用同一個正則表達式解析所有的BBCode。這就是我的意思是「分解成多個步驟」。 – Jon

1

如何在兩個步驟做這個:

首先添加段落標記在每行不開始/結束與==

$firststep = preg_replace('/^(?![ \t]*==.*==[ \t]*$).+/m', '<p>\0</p>', $subject); 

然後添加周圍所有做過開始行標題標記/以==結尾:

$result = preg_replace('/^[ \t]*==[ \t]*(.*?)[ \t]*==[ \t]*$/m', '<h2>\1</h2>', $firststep); 
+0

當然是一個很好的解決方案,但是我不能相信我的客戶總是把他們的標題標記放在單獨的行上。 – Kokos