正则表达式替换脚本标签外的文本
Regex replace text outside script tag
我有这个HTML:
"This is simple html text <script language="javascript">simple simple text text</script> text"
我只需要匹配脚本标签之外的单词。我的意思是,如果我想匹配“simple”和“text”,我应该只从“This is simple html text”和最后一部分“text”获得结果——结果将是“simple”1 匹配, “文本”2 个匹配项。谁能帮我解决这个问题?我正在使用 PHP.
我在标签外找到了匹配文本的类似答案:
(text|simple)(?![^<]*>|[^<>]*</)
Regex replace text outside html tags
但无法为特定标签(脚本)工作:
(text|simple)(?!(^<script*>)|[^<>]*</)
ps:这个问题不是重复的(strip_tags, remove javascript)。因为我不是要剥离标签,或者 select 脚本标签内的内容。我正在尝试替换标签 "script".
之外的内容
如果确定 script
会出现,那么只需匹配
(.*?)<script.*</script>(.*)
标签外的文本将出现在子匹配 1 和 2 中。如果 script
是可选的,则执行 (.*?)(<script.*</script>)?(.*)
。
这是另一个解决方案
([\w\s]*)(?:<script.*?\/script>)(.*)$
上的演示
仅供参考,就标签而言,不可能忽略单个标签
不解析所有标签。
您可以 SKIP/FAIL 过去 html 标签和不可见的内容。
这将找到您要查找的单词。
'~<(?:(?:(?:(script|style|object|embed|applet|noframes|noscript|noembed)(?:\s+(?>"[\S\s]*?"|\'[\S\s]*?\'|(?:(?!/>)[^>])?)+)?\s*>)[\S\s]*?</\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]*? </ \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 )
或者,一种更快的方法是同时匹配标签 和 您的文本
寻找。
匹配标签会越过它们。
如果您要进行替换,请使用回调来确定要替换的内容。
第 1 组是 TAG 或 不可见内容 运行.
第 3 组是您要替换的词。
因此,在回调中,如果第 1 组匹配,则 return 第 1 组。
如果第 3 组匹配,请替换为您想要替换的内容。
正则表达式
'~(<(?:(?:(?:(script|style|object|embed|applet|noframes|noscript|noembed)(?:\s+(?>"[\S\s]*?"|\'[\S\s]*?\'|(?:(?!/>)[^>])?)+)?\s*>)[\S\s]*?</\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 标签的示例:
我的模式将使用 (*SKIP)(*FAIL)
取消匹配的脚本标签及其内容。
text
和 simple
将在每次符合条件的情况下匹配。
正则表达式模式:~<script.*?/script>(*SKIP)(*FAIL)|text|simple~
Pattern / Replacement Demo Link
代码:(Demo)
$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',
)
我有这个HTML:
"This is simple html text <script language="javascript">simple simple text text</script> text"
我只需要匹配脚本标签之外的单词。我的意思是,如果我想匹配“simple”和“text”,我应该只从“This is simple html text”和最后一部分“text”获得结果——结果将是“simple”1 匹配, “文本”2 个匹配项。谁能帮我解决这个问题?我正在使用 PHP.
我在标签外找到了匹配文本的类似答案:
(text|simple)(?![^<]*>|[^<>]*</)
Regex replace text outside html tags
但无法为特定标签(脚本)工作:
(text|simple)(?!(^<script*>)|[^<>]*</)
ps:这个问题不是重复的(strip_tags, remove javascript)。因为我不是要剥离标签,或者 select 脚本标签内的内容。我正在尝试替换标签 "script".
之外的内容如果确定 script
会出现,那么只需匹配
(.*?)<script.*</script>(.*)
标签外的文本将出现在子匹配 1 和 2 中。如果 script
是可选的,则执行 (.*?)(<script.*</script>)?(.*)
。
这是另一个解决方案
([\w\s]*)(?:<script.*?\/script>)(.*)$
上的演示
仅供参考,就标签而言,不可能忽略单个标签
不解析所有标签。
您可以 SKIP/FAIL 过去 html 标签和不可见的内容。
这将找到您要查找的单词。
'~<(?:(?:(?:(script|style|object|embed|applet|noframes|noscript|noembed)(?:\s+(?>"[\S\s]*?"|\'[\S\s]*?\'|(?:(?!/>)[^>])?)+)?\s*>)[\S\s]*?</\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]*? </ \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 )
或者,一种更快的方法是同时匹配标签 和 您的文本
寻找。
匹配标签会越过它们。
如果您要进行替换,请使用回调来确定要替换的内容。
第 1 组是 TAG 或 不可见内容 运行.
第 3 组是您要替换的词。
因此,在回调中,如果第 1 组匹配,则 return 第 1 组。
如果第 3 组匹配,请替换为您想要替换的内容。
正则表达式
'~(<(?:(?:(?:(script|style|object|embed|applet|noframes|noscript|noembed)(?:\s+(?>"[\S\s]*?"|\'[\S\s]*?\'|(?:(?!/>)[^>])?)+)?\s*>)[\S\s]*?</\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 标签的示例:
我的模式将使用 (*SKIP)(*FAIL)
取消匹配的脚本标签及其内容。
text
和 simple
将在每次符合条件的情况下匹配。
正则表达式模式:~<script.*?/script>(*SKIP)(*FAIL)|text|simple~
Pattern / Replacement Demo Link
代码:(Demo)
$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',
)