【问题标题】:Perl regular expression match tags that may not be therePerl 正则表达式匹配可能不存在的标签
【发布时间】:2014-07-15 15:09:51
【问题描述】:

我正在尝试构建一个 Perl 正则表达式来匹配这样的字符串:

no tags
beginning<tag>this is tag</tag>rest of line
<tag1>this is tag1</tag1>
<tag1>this is tag1</tag1>rest of line

我想使用分组来提取标签以及它们之间的内容。

我试过用这个:

$a="beginning<tag>this is tag</tag>rest of line";

print "a=$a\n\n";

($x0, $x1, $x2, $x3, $x4, $x5) = ($a =~ /(.*?)(<tag>)(.*)(<\/tag>)(.*)/);

print "x0=$x0\n";
print "x1=$x1\n";
print "x2=$x2\n";
print "x3=$x3\n";
print "x4=$x4\n";


a=beginning<tag>this is tag</tag>rest of line

x0=beginning
x1=<tag>
x2=this is tag
x3=</tag>
x4=rest of line

我想要什么,但如果这是源字符串:

a=there are no tags

x0=
x1=
x2=
x3=
x4=

没有匹配项。

【问题讨论】:

  • 不要使用正则表达式解析 HTML。使用适当的 HTML 解析模块。 您无法使用正则表达式可靠地解析 HTML,并且您将面临悲伤和挫败感。一旦 HTML 与您的期望发生变化,您的代码就会被破坏。请参阅htmlparsing.com/phpthis SO thread,了解如何使用已经编写、测试和调试过的 PHP 模块正确解析 HTML。
  • 您可以随时将模块的代码直接复制/粘贴到您的程序中。

标签: regex perl html-parsing


【解决方案1】:

这就是你要找的东西(见online demo):

(?m)(.*?)(?:$|(<[^>]*>)([^<]*)(</[^>]*>)(.*))

这是如何工作的?

  1. 顶部的(?m) 多行修饰符确保$ 可以匹配每一行的结尾,因为您似乎正在处理一个文件。
  2. 第一个捕获组(.*?)后跟一个交替:要么是$行尾,它允许你在没有标签的情况下捕获字符串; | 或者你的标签和可选的尾巴。

【讨论】:

  • 就是这样 - 我不知道 (?:) 交替运算符。
  • @user1279887 很高兴听到它对您有用! | 是交替运算符,(?: something) 只是一个非捕获组,因此我们不会通过添加捕获括号来弄乱您的组号。 :)
  • (?:$|...)代替(?:...)?可能更清楚。
  • @Miller 这将创建一个正则表达式,其中每个组件都是可选的,从而导致各种怪异。例如,请参阅this demo。这可能是他无法解决的原始问题的一部分,这就是我提供$ 解决方案的原因。 :)
  • @zx81 您提供的正则表达式与我提供的正则表达式在功能上没有区别。正则表达式中的 4 个捕获组也是“可选”。所以如果有“wierdness”发生,它们都会同时发生。
猜你喜欢
  • 2017-08-04
  • 2014-08-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多