Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
正则表达式匹配除<;之外的所有HTML标记;p>;及</p>;_Html_Regex_Perl - Fatal编程技术网

正则表达式匹配除<;之外的所有HTML标记;p>;及</p>;

正则表达式匹配除<;之外的所有HTML标记;p>;及</p>;,html,regex,perl,Html,Regex,Perl,我需要在Perl中使用正则表达式匹配并删除所有标记。我有以下资料: <\\??(?!p).+?> 但这仍然与结束标记相匹配。还有关于如何与结束标记匹配的提示吗 注意,这是在xhtml上执行的。假设这将在PERL中工作,就像在声称使用PERL兼容语法的语言中一样: /]*>/ 编辑: 但不幸的是,这与或标记不匹配 /<\/?(?!p>|p )[^>]+>/ 也许是这个 /<\/?([^p](\s.+?)?|..+?)>/ /| p)[^>]

我需要在Perl中使用正则表达式匹配并删除所有标记。我有以下资料:

<\\??(?!p).+?>

但这仍然与结束标记相匹配。还有关于如何与结束标记匹配的提示吗


注意,这是在xhtml上执行的。

假设这将在PERL中工作,就像在声称使用PERL兼容语法的语言中一样:

/]*>/

编辑:

但不幸的是,这与
标记不匹配

/<\/?(?!p>|p )[^>]+>/
也许是这个

/<\/?([^p](\s.+?)?|..+?)>/
/| p)[^>]+>/

这应该包括也有属性的标签。

试试这个,它应该可以工作:

<p onclick="document.location.href='http://www.evil.com'">Clickable text</p>
//
说明:它可以匹配除“p”之外的单个字母,后跟可选空格和更多字符,也可以匹配多个字母(至少两个)


/编辑:我添加了处理
p
标记中属性的功能。

由于HTML不是一种常规语言,我不希望正则表达式能够很好地匹配它。他们可能会接受这项任务(虽然我不相信),但我会考虑去别处看看;我确信perl必须有一些现成的库来操作HTML

无论如何,我认为您想要匹配的是非贪婪的(我不知道perl的regexp语法有多奇怪,所以我无法进一步帮助)。我假设\s表示空白。也许不是。无论哪种方式,您都需要一些匹配属性的内容,这些属性通过空格从标记名偏移。但这比这更困难,因为人们经常在脚本和注释中放上未加修饰的尖括号,甚至可能是引用的属性值,这是您不想匹配的

正如我所说,我并不认为regexp是适合这项工作的工具


因为HTML不是一种常规语言


HTML不是,但HTML标记是,它们可以用正则表达式进行适当的描述。

您可能还应该删除标记上的任何属性,因为坏人可能会执行以下操作:

<(?!\/?p(?=>|\s.*>))\/?.*?>

x/
<           # Match open angle bracket
(?!         # Negative lookahead (Not matching and not consuming)
    \/?     # 0 or 1 /
    p           # p
    (?=     # Positive lookahead (Matching and not consuming)
    >       # > - No attributes
        |       # or
    \s      # whitespace
    .*      # anything up to 
    >       # close angle brackets - with attributes
    )           # close positive lookahead
)           # close negative lookahead
            # if we have got this far then we don't match
            # a p tag or closing p tag
            # with or without attributes
\/?         # optional close tag symbol (/)
.*?         # and anything up to
>           # first closing tag
/

可点击文本

最简单的方法是使用这里人们建议的正则表达式搜索带有属性的<p>标记,并将它们替换为不带属性的标记。为了安全起见。

我想到了这个:

(
    <               # < opening tag
        [^pP].*?    # p non-p character, then non-greedy anything
    >               # > closing tag
|                   #   ....or....
    </              # </
        [^pP]       # a non-p tag
    >               # >
)
\s.*)\/?*>
x/
<#匹配开口角支架
(?!#消极前瞻(不匹配也不消耗)
\/?#0或1/
p#p
(?=#正向前瞻(匹配且不消耗)
>#>-无属性
|#或
\s#空格
有什么事吗
>#右尖括号-带属性
)#关闭正向前瞻
)#关闭负面展望
#如果我们已经走了这么远,那么我们就不匹配了
#p标记或结束p标记
#有无属性
\/?         # 可选关闭标记符号(/)
.*?         # 有什么事吗
>#第一个结束标记
/
现在,这将处理带属性或不带属性的p标记和结束p标记,但将匹配带属性或不带属性的pre和类似标记


它不会去掉属性,但我的源数据不会把它们放进去。稍后我可能会更改此选项以执行此操作,但这就足够了。

不确定为什么要执行此操作-用于HTML清理的正则表达式并不总是最好的方法(您需要记住清理属性等,删除javascript:hrefs等)。。。但是,要匹配非
的HTML标记,需要使用正则表达式:

(|)

冗长的:

# Remove all HTML except "p" tags
$html =~ s{<(?>/?)(?:[^pP]|[pP][^\s>/])[^>]*>}{}g;
(
<#<开始标签
[^pP].*p非-p字符,则为非贪婪字符
>#>结束标记
|#……或。。。。
)
如果您坚持使用正则表达式,在大多数情况下,类似的方法都会奏效:

s{
  <             # opening angled bracket
  (?>/?)        # ratchet past optional / 
  (?:
    [^pP]       # non-p tag
    |           # ...or...
    [pP][^\s>/] # longer tag that begins with p (e.g., <pre>)
  )
  [^>]*         # everything until closing angled bracket
  >             # closing angled bracket
 }{}gx; # replace with nothing, globally

接受文件名、打开的文件句柄或字符串形式的输入。将上述代码包装到库中并使目的地可配置(即,不只是像上面那样打印)并不难。与尝试使用正则表达式相比,结果将更加可靠、可维护,并且可能更快(HTML::Parser使用基于C的后端)。

您可能还希望在p标记中的“p”之前允许空白。不确定您会多久遇到这种情况,但是完全有效的HTML。

在我看来,尝试用HTML解析器以外的任何东西解析HTML只会让人感到痛苦。HTML是一种非常复杂的语言(这是创建XHTML的主要原因之一,它比HTML简单得多)

例如,这:

 <(?>/?)(?!p).+?>

只需很少的努力即可使原始正则表达式工作:

<(?!\/?(p|a|b|i|u|br)(?=>|\s?.*>))\/?.*?>
/?)(?!p.+?>
问题是/?(或\?)在断言失败后放弃匹配的内容。在其周围使用非回溯组(?>…)会注意它不会释放匹配的斜杠,因此(?p)断言始终锚定到标记文本的开头


(也就是说,我同意通常用正则表达式解析HTML不是一种好方法)。

我使用了Xetius正则表达式,它工作得很好。除了一些flex生成的标记之外,这些标记可以是:
,内部没有空格。我试着用一个简单的?在\s之后,它看起来正在工作:

#!/usr/bin/perl
$regex = '(<\/?p[^>]*>)|<[^>]*>';
$subject = 'Bad html <a> </I> <p>My paragraph</p> <i>Italics</i> <p class="blue">second</p>';
($replaced = $subject) =~ s/$regex/$1/eg;
print $replaced . "\n";
\s?*>)\/?*>
我使用它来清除flex生成的html文本中的标记,因此我还添加了更多例外标记:

~(<\/?[^>]*(?<!<\/p|p)>)~ig
\s?*>)\/?*>

Xetius,重新提出这个古老的问题,因为它有一个没有提到的简单解决方案。(在为某个客户进行研究时发现了您的问题。)

所有关于使用正则表达式解析html的免责声明,下面是一个简单的方法

#/usr/bin/perl
$regex
<(?!\/?p(?=>|\s?.*>))\/?.*?>
<(?!\/?(p|a|b|i|u|br)(?=>|\s?.*>))\/?.*?>
#!/usr/bin/perl
$regex = '(<\/?p[^>]*>)|<[^>]*>';
$subject = 'Bad html <a> </I> <p>My paragraph</p> <i>Italics</i> <p class="blue">second</p>';
($replaced = $subject) =~ s/$regex/$1/eg;
print $replaced . "\n";
~(<\/?[^>]*(?<!<\/p|p)>)~ig