gpt4 book ai didi

php - html 文档中的正则表达式 : match all but every <(pre|code|textarea)>(. *?)

转载 作者:太空狗 更新时间:2023-10-29 15:05:18 24 4
gpt4 key购买 nike

这是一个挑战!

正如标题所说,我想匹配 HTML 文档中除 <pre>、<code> 和 <textarea> 标签之外的所有内容(例如,您可以尝试以下文本)。

在我的情况下,目的是压缩 html,删除\n\t\r 和其他清理,除非像 textarea 那样严格要求。

当我在 PHP 中工作时,我也考虑过提取这些标签内容,在 PHP 中处理其余部分并将它们重新注入(inject)到 PHP 中。但我很好奇在正则表达式中做到这一点的方法!

我试过伟大的在线编辑器:http://regex101.com/表达式 ((?=.?)((?!<pre>).))带有标志 'msg' 但不是我想要的。

任何帮助将非常感激!

Lorem ipsum dolor sat amet,consectetuer adipiscing elit,sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat。 Ut wisi enim ad minim veniam, quis nostrud exerciation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat。

Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse Molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent praesent praesent de luptilitatum nulla facilisis at vero eros et accumsan et iusto odio dignissim Nam Liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum。
Typi non habent claritatem insitam; est usus legentis in iis qui facit eorum claritatem。

调查示威游行 lectores legere me lius quod ii legunt saepius。
Claritas est etiam processus dynamicus,qui sequitur mutationem consuetudium lectorum。
Mirum est notare quam littera gothica、quam nunc putamus parum claram、anteposuerit litterarum formas humanitatis per seacula quarta decima et quinta decima。
Eodem modo typi,qui nunc nobis videntur parum clari, future 的未婚夫。

最佳答案

你可以使用这个:

$pattern = <<<'LOD'
~
# definitions :
(?(DEFINE) (?<tagBL> pre | code | textarea | style | script )
(?<tagContent> < (\g<tagBL>) \b .*? </ \g{-1} > )
(?<tags> < [^>]* > )
(?<cdata> <!\[CDATA .*? ]]> )

(?<exclusionList> \g<tagContent> | \g<cdata> | \g<tags>)
)

# pattern :
\g<exclusionList> (*SKIP) (*FAIL) | \s+
~xsi
LOD;

$html = preg_replace($pattern, ' ', $html);

请注意,这是一种通用方法,您可以通过在排除列表中添加或删除内容来轻松地使其适应特定情况。
如果您需要其他类型的替换,您也可以通过使用捕获组和 preg_replace_callback() 来调整它。 .

另一个注意事项:html 标签保持打开状态,直到结束标签。如果结束标签不存在,则该标签之后的所有内容都属于该标签,直到字符串结束。要解决这个问题,您可以更改 </ \g{-1} >(?: </ (?:\g{-1}| head | body | html) > | $)例如在标签内容定义中,或者编写更高级的规则。

编辑:
您可以在 the php manual 中找到一些信息:

nowdoc 语法是定义字符串的另一种语法。在不修改其布局并避免有关是否转义引号的问题的情况下,使多行字符串更具可读性是非常有用的。 nowdoc 语法与单引号具有相同的行为,即变量不会被解释为转义格式标记,如 \t\n .如果您想要与双引号相同的行为,请使用 heredoc 语法。

您可以在 http://pcre.org/pcre.txt 中找到一些信息:

首先:模式分隔符

大多数时候,人们用 / 来写他们的模式。分隔符。 /Gnagnagna/ , /blablabla/ixUums等。但是当他们编写一个包含大约一千或一百万个斜杠字符的模式时,他们更喜欢逐个转义千位斜杠,以选择另一个分隔符!使用 PHP,如果它不是字母数字字符,您可以选择所需的模式分隔符。我选择了 ~而不是 /出于三个原因:
  • 如果我选择~ , 我不必转义斜杠,因为分隔符和文字字符没有歧义。
  • 我从来没有在这个网站的高峰月份看到有人要求一个里面有波浪号的图案。
  • 我敢肯定,如果有一天有人问一个带波浪号的模式,我遇到了第三种。

  • 第二:如何让长模式更具可读性?

    PCRE(Perl 通用正则表达式,PHP 使用的正则表达式引擎)有办法使代码更具可读性。这些方式与您在公共(public)代码中可以找到的完全相同:
  • 您可以忽略空格
  • 您可以添加评论
  • 您可以定义子模式

  • 对于 1 和 2,很简单,您只需要添加 x 修饰符(这就是您在末尾找到 x 的原因)。 x 修饰符允许忽略空格的详细模式,您可以在其中添加这样的注释 # comment在行尾。

    关于子模式:您可以使用命名组,例如:而不是写 ~([0-9]+)~要匹配和捕获组 1 内的数字,您可以写 ~(?<number>[0-9]+)~ .现在,使用这个命名的子模式,您可以使用 \g{number} 引用捕获的内容。或使用 \g<number> 到模式本身, 模式中的任何位置。例子:
    ~^(?<num>[0-9]+)(?<letter>[a-z]+)\g<num>\g<letter>$~

    将匹配 45ab67cd
    ~^(?<num>[0-9]+)(?<letter>[a-z]+)\g{num}\g<letter>$~

    将匹配 45ab45cd但不是 45ab67cd
    在这两个示例中,命名子模式是主模式的一部分并匹配字符串的开头。但是使用 (?(DEFINE)...)语法,您可以在主模式之外定义它们,因为您在这些括号之间编写的所有内容都不匹配。
    ~(?(DEFINE)(?<num>[0-9]+)(?<letter>[a-z]+))^\g<num>\g<letter>$~

    不匹配 45ab67cd ,因为都在 DEFINE里面匹配部分将被忽略,但是:
    ~(?(DEFINE)(?<num>[0-9]+)(?<letter>[a-z]+))^\g<num>\g<letter>\g<num>\g<letter>$~

    做。

    第三:相对反向引用

    在模式中使用捕获组时,可以使用对捕获内容的引用,例如:
    $str = 'cats meow because cats are bad.';

    $pattern = '~^(\w+) \w+ \w+ \1 \w+ \w+\.$~';

    var_dump(preg_match($pattern, $str));

    当前代码返回 true因为模式匹配字符串。在图案中, \1指的是第一个捕获组的内容 ( cats )。而不是写 \1 ,您可以使用 oniguruma 语法和写作 \g{1}也指第一个捕获组,它是相同的。

    现在,如果你想引用 的内容最后 捕获组,但您不关心组的编号(或名称),可以使用 相关引用通过写作 \g{-1} (即我左边的第一组)

    第四:修饰符 xsi

    模式的一般行为可以通过修饰符来改变。这里我使用了三个修饰符:
    x # for verbose mode
    i # make the pattern case insensitive (i.e. '~CaT~i' will match "cat")
    s # (singleline mode): by default the . doesn't match newline, with the s modifier it does.

    最后:回溯控制动词

    回溯控制动词是从 perl 正则表达式引擎继承的实验性功能(状态在 perl 中也是实验性的,但如果没有人使用它,它不会改变)。

    什么是回溯?

    如果我尝试匹配 "aaaaab"~a+ab~正则表达式引擎,自 +是一个贪婪的量词,将捕获所有 a (五一),但之后它只留下一个 b与子模式不匹配 ab .正则表达式引擎的唯一方法是取回一个 a ,然后可以匹配 ab .这是正则表达式引擎的默认行为。

    更多关于回溯 herehere .

    回溯控制动词是强制正则表达式引擎具有您想要的子模式行为的工具。

    这里我用了两个动​​词: (*SKIP)(*FAIL) (*FAIL)是最容易的。子模式被迫立即失败。
    (*SKIP) :当子模式在此动词之后失败时,正则表达式引擎无权回溯此动词之前匹配的字符。并且此内容不能重用于另一个替代子模式。

    我明白所有这些事情并不总是那么容易,但我希望,一步一步,有一天,所有这些事情都会为你一清二楚。

    关于php - html 文档中的正则表达式 : match all but every <(pre|code|textarea)>(. *?)</\\1>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20421646/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com