2009-07-25 131 views
0

我正在尋找一個正則表達式來提取不包含HTML的所有相鄰行塊標記,但它們可以包含HTML 內聯標記正則表達式提取不包含HTML塊標記的行

舉例來說,如果我有以下的文字...

bla bla bla bla 
bla <code>bla bla</code> bla 
bla bla bla bla 
<img src="" alt="" /> 
bla bla bla bla 
<div> bla bla bla 
bla bla bla 

...我想只提取以下各行...

bla bla bla bla 
bla <code>bla bla</code> bla 
bla bla bla bla 
<img src="" alt="" /> 
bla bla bla bla 

這是可以做到的正則表達式?

更新:我正在使用PHP,我也有一個包含這些塊標籤名稱的變量。 塊標籤是開放標籤還是關閉標籤無關緊要。

$blockTags = "h1|h2|h3|h4|h5|h6|hr|ol|ul|li|pre|blockquote|p|table|tr|td|div"; 
+2

使用正則表達式,一切皆有可能。 :) – cakeforcerberus 2009-07-25 22:53:51

+4

@semirhage:哦,我希望我現在能夠冷靜點評。 – Sean 2009-07-25 22:54:54

+0

聽起來像達斯Eru沒有幽默感。 – 2009-07-25 22:57:51

回答

2

別再找了。你的任務需要一個解析器,它可以理解HTML標記打開和關閉的時間,這是古典正則表達式無法做到的。

現代正則表達式可能能夠拉開這樣的詭計,但是你會構造出世界上曾經見過的最可怕的不可讀正則表達式(好吧,不是,但是很接近),如果你需要改變行爲,你最終可能會重寫整個事情。因此,編寫一個相對簡單的解析器來爲你做,並且不要花費數小時來編寫一些其他人稍後會花費數小時試圖理解的正則表達式。順便說一下,如果你問一個正則表達式問題,請指定你正在使用的語言。他們在不同的語言中略有不同。

1

嗯,你可以做的是,你可以先過濾不包含的東西任何HTML標籤,如

[^<>]* 

,然後檢查線路有任何HTML內嵌標籤的線路:

<(/?)(code|img|...)(/?)> 

其餘的將包含塊標籤。
不知道這是否足夠準確,但你。

1

這不是「只有一個正則表達式」,但它應該做的工作,考慮你的輸入字符串是$str

$lines = explode(PHP_EOL, $str); 
$linesToKeep = array(); 

foreach ($lines as $line) { 
    if (!preg_match('#</?(' . $blockTags . ')>#', $line)) { 
     $linesToKeep[] = $line; 
    } 
} 

// Et voila ;-) 
$strOK = implode(PHP_EOL, $linesToKeep); 
var_dump($strOK); 

幾句話:

  • 它炸串在線工作(因爲你想保持或拒絕一行一行)。
  • 它由線
  • 環行,如果該行不包含<TAG></TAG>,是放到底$linesToKeep陣列
  • 中,在輸出中字符串是從什麼是該數組中內置

雖然...但這個很容易理解,我猜(不是某種有點「正則表達式」或任何人都無法維護的東西^^)

編輯:當我重新閱讀OP時,我是通俗的編輯最後一行被排除在外,而這不是我的代碼...如果你想排除有開口標記線,和一個它之後,這裏的另一個命題:

$lines = explode(PHP_EOL, $str); 
$linesToKeep = array(); 
$i = 0; 
$numLines = count($lines); 

for ($i=0 ; $i<$numLines ; $i++) { 
    $line = $lines[$i]; 
    if (!preg_match('#</?(' . $blockTags . ')>#', $line)) { 
     $linesToKeep[] = $line; 
    } else { 
     if (preg_match('#<(' . $blockTags . ')>#', $line)) { 
      // Opening tag, skip next line too ? 
      $i++; 
     } 
    } 
} 

$strOK = implode(PHP_EOL, $linesToKeep); 
var_dump($strOK); 

如果你想要跳過行,直到結束標記,你可以做到這一點,我把$i++ - 但它變得越來越難以閱讀/理解^^ (和「解析」手動可能不是一個好主意,如果你想要得到一些複雜的東西^^)