正则表达式提取不包含HTML块标记的行

问题描述:

我正在寻找一个正则表达式来提取不包含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

别再找了。你的任务需要一个解析器,它可以理解HTML标记打开和关闭的时间,这是古典正则表达式无法做到的。

现代正则表达式可能能够拉开这样的诡计,但是你会构造出世界上曾经见过的最可怕的不可读正则表达式(好吧,不是,但是很接近),如果你需要改变行为,你最终可能会重写整个事情。因此,编写一个相对简单的解析器来为你做,并且不要花费数小时来编写一些其他人稍后会花费数小时试图理解的正则表达式。顺便说一下,如果你问一个正则表达式问题,请指定你正在使用的语言。他们在不同的语言中略有不同。

嗯,你可以做的是,你可以先过滤不包含的东西任何HTML标签,如

[^<>]* 

,然后检查线路有任何HTML内嵌标签的线路:

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

其余的将包含块标签。
不知道这是否足够准确,但你。

这不是“只有一个正则表达式”,但它应该做的工作,考虑你的输入字符串是$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++ - 但它变得越来越难以阅读/理解^^ (和“解析”手动可能不是一个好主意,如果你想要得到一些复杂的东西^^)