正则表达式替换脚本标签外的文本

问题描述 投票:0回答:4

我有这个 HTML:

“这是简单的 html 文本  文本”

我只需要匹配脚本标签之外的单词。我的意思是,如果我想匹配“simple”和“text”,我应该只从“This is simple html text”和最后一部分“text”得到结果——结果将是“simple”1匹配,“text”2火柴。谁能帮我解决这个问题?我正在使用 PHP。

我在标签外找到了匹配文本的类似答案:

(text|simple)(?![^<]*>|[^<>]*</)

正则表达式替换 html 标签外的文本

但无法为特定标签(脚本)工作:

(text|simple)(?!(^<script*>)|[^<>]*</)

ps:此题不重复(strip_tags,去掉javascript)。因为我不是要剥离标签,或选择脚本标签内的内容。我正在尝试替换标签“脚本”之外的内容。

php html regex preg-replace
4个回答
1
投票

我的模式将使用

(*SKIP)(*FAIL)
取消匹配的脚本标签及其内容的资格。

text
simple
将在每次符合条件的情况下匹配。

正则表达式模式:

~<script.*?/script>(*SKIP)(*FAIL)|text|simple~

图案/替换演示链接

代码:(演示

$strings=['This has no replacements',
    'This simple text has no script tag',
    'This simple text ends with a script tag <script language="javascript">simple simple text text</script>',
    'This is simple html text is split by a script tag <script language="javascript">simple simple text text</script> text',
    '<script language="javascript">simple simple text text</script> this text starts with a script tag'
];

$strings=preg_replace('~<script.*?/script>(*SKIP)(*FAIL)|text|simple~','***replaced***',$strings);

var_export($strings);

输出:

array (
  0 => 'This has no replacements',
  1 => 'This ***replaced*** ***replaced*** has no script tag',
  2 => 'This ***replaced*** ***replaced*** ends with a script tag <script language="javascript">simple simple text text</script>',
  3 => 'This is ***replaced*** html ***replaced*** is split by a script tag <script language="javascript">simple simple text text</script> ***replaced***',
  4 => '<script language="javascript">simple simple text text</script> this ***replaced*** starts with a script tag',
)

0
投票

如果确定

script
将出现,那么只需匹配

(.*?)<script.*</script>(.*)

标签外的文本将出现在子匹配 1 和 2 中。如果

script
是可选的,那么执行
(.*?)(<script.*</script>)?(.*)
.


0
投票

这是另一个解决方案

([\w\s]*)(?:<script.*?\/script>)(.*)$

这是https://regex101.com/r/1Lthi8/1

上的演示

0
投票

仅供参考,就标签而言,不可能忽略单个标签
无需解析所有标签。

您可以跳过/失败过去的html标签和不可见的内容。
这将找到您要查找的单词。

'~<(?:(?:(?:(script|style|object|embed|applet|noframes|noscript|noembed)(?:\s+(?>"[\S\s]*?"|\'[\S\s]*?\'|(?:(?!/>)[^>])?)+)?\s*>)[\S\s]*?</\1\s*(?=>))|(?:/?[\w:]+\s*/?)|(?:[\w:]+\s+(?:"[\S\s]*?"|\'[\S\s]*?\'|[^>]?)+\s*/?)|\?[\S\s]*?\?|(?:!(?:(?:DOCTYPE[\S\s]*?)|(?:\[CDATA\[[\S\s]*?\]\])|(?:--[\S\s]*?--)|(?:ATTLIST[\S\s]*?)|(?:ENTITY[\S\s]*?)|(?:ELEMENT[\S\s]*?))))>(*SKIP)(?!)|(?:text|simple)~'

https://regex101.com/r/7ZGlvW/1

格式化

    <
    (?:
         (?:
              (?:
                                                 # Invisible content; end tag req'd
                   (                             # (1 start)
                        script
                     |  style
                     |  object
                     |  embed
                     |  applet
                     |  noframes
                     |  noscript
                     |  noembed 
                   )                             # (1 end)
                   (?:
                        \s+ 
                        (?>
                             " [\S\s]*? "
                          |  ' [\S\s]*? '
                          |  (?:
                                  (?! /> )
                                  [^>] 
                             )?
                        )+
                   )?
                   \s* >
              )

              [\S\s]*? </ \1 \s* 
              (?= > )
         )

      |  (?: /? [\w:]+ \s* /? )
      |  (?:
              [\w:]+ 
              \s+ 
              (?:
                   " [\S\s]*? " 
                |  ' [\S\s]*? ' 
                |  [^>]? 
              )+
              \s* /?
         )
      |  \? [\S\s]*? \?
      |  (?:
              !
              (?:
                   (?: DOCTYPE [\S\s]*? )
                |  (?: \[CDATA\[ [\S\s]*? \]\] )
                |  (?: -- [\S\s]*? -- )
                |  (?: ATTLIST [\S\s]*? )
                |  (?: ENTITY [\S\s]*? )
                |  (?: ELEMENT [\S\s]*? )
              )
         )
    )
    >
    (*SKIP)
    (?!)
 |  
    (?: text | simple )

或者,一种更快的方法是匹配两个标签AND你的文本
寻找。

匹配标签移动过去。

如果您正在进行替换,请使用回调来确定要替换的内容。
第 1 组是 TAGInvisible Content run.
第 3 组是您要替换的词。

因此,在回调中,如果第 1 组匹配,则返回第 1 组。
如果第 3 组匹配,请替换为您想要替换的内容。

正则表达式

'~(<(?:(?:(?:(script|style|object|embed|applet|noframes|noscript|noembed)(?:\s+(?>"[\S\s]*?"|\'[\S\s]*?\'|(?:(?!/>)[^>])?)+)?\s*>)[\S\s]*?</\2\s*(?=>))|(?:/?[\w:]+\s*/?)|(?:[\w:]+\s+(?:"[\S\s]*?"|\'[\S\s]*?\'|[^>]?)+\s*/?)|\?[\S\s]*?\?|(?:!(?:(?:DOCTYPE[\S\s]*?)|(?:\[CDATA\[[\S\s]*?\]\])|(?:--[\S\s]*?--)|(?:ATTLIST[\S\s]*?)|(?:ENTITY[\S\s]*?)|(?:ELEMENT[\S\s]*?))))>)|(text|simple)~'

https://regex101.com/r/7ZGlvW/2


这个正则表达式类似于 SAX 和 DOM 解析器解析标签的方式。
我已经在 SO 上发布了数百次。

以下是如何删除所有 html 标签的示例:

https://regex101.com/r/oCVkZv/1

© www.soinside.com 2019 - 2024. All rights reserved.