Javascript 使用子combinator时,从HTML字符串解析CSS的正则表达式失败
我在JavaScript代码中使用以下正则表达式从更大的HTML代码字符串中解析CSS(样式标记及其内容Javascript 使用子combinator时,从HTML字符串解析CSS的正则表达式失败,javascript,html,css,regex,Javascript,Html,Css,Regex,我在JavaScript代码中使用以下正则表达式从更大的HTML代码字符串中解析CSS(样式标记及其内容 const regex=/]*>([^>]*?)/g 这很好,除非样式标记中包含的CSS代码包含CSS选择器(例如div>a之类的CSS选择器)。我想这与以下事实有关:这个特定的选择器使用,这也是用于在HTML中创建实际的标记的语法,但我对正则表达式的理解还不够透彻,不知道是否有办法解决这个问题 const str1='div{color:red;}a{color:green;}你好 有没
const regex=/]*>([^>]*?)/g
这很好,除非样式标记中包含的CSS代码包含CSS选择器(例如div>a
之类的CSS选择器)。我想这与以下事实有关:这个特定的选择器使用
,这也是用于在HTML中创建实际的
标记的语法,但我对正则表达式的理解还不够透彻,不知道是否有办法解决这个问题
const str1='div{color:red;}a{color:green;}你好
有没有办法修改正则表达式,使其在CSS代码包含
时也能工作
更新
根据评论中的讨论作出澄清
在我的特殊情况下,我通过正则表达式(而不是说通过document.querySelectorAll('style')
)解析DOM)来应对这一挑战,因为代码需要能够在不同的上下文中运行(JS运行时现在可以在不同的地方找到,从浏览器到节点再到Adobe套件)所以我在寻找一个上下文无关的解决方案
目前看来@Maxt8r将内容表达式更改为[\S\S]*?
的解决方案似乎已经奏效了更安全的正则表达式是这样的
/(?:)[^>])?)+)\2)?\s*>([\s\s]*?)/
我建议你用这个。内容在第3组
如果要匹配所有不可见内容,请将其替换为stylescript | style | object | embed | applet | noframes | noscript | noembed
阅读
(?:
<
( style ) # (1), Invisible content; end tag req'd
(?:
\s+
(?=
( # (2 start)
(?:
" [\S\s]*? "
| ' [\S\s]*? '
| (?:
(?! /> )
[^>]
)?
)+
) # (2 end)
)
\2
)?
\s* >
)
( [\S\s]*? ) # (3)
</ \1 \s* >
(?)
<
(样式)#(1),不可见内容;需要结束标记
(?:
\s+
(?=
(#(2开始)
(?:
“[\S\S]*?”
|“[\S\S]*?”
| (?:
(?! /> )
[^>]
)?
)+
)#(二完)
)
\2
)?
\s*>
)
([\S\S]*?)#(3)
如果有人对此感到好奇,则前瞻性断言将匹配其余的
样式标记内部attr/vals不仅专门进行验证,
但也要确保样式标签不是独立的(即使是打字错误)。
断言的内容是被动的,不受回溯的影响,
并且被捕获并插入刚刚经过断言的位置,其中回溯
环境是,但现在反向引用只是一个文字。
在像php这样的非JS环境中,这是通过替换
原子组(>..)
代替断言。更安全的正则表达式是
/(?:)[^>])?)+)\2)?\s*>([\s\s]*?)/
我建议你用这个。内容在第3组
如果要匹配所有不可见内容,请将其替换为stylescript | style | object | embed | applet | noframes | noscript | noembed
阅读
(?:
<
( style ) # (1), Invisible content; end tag req'd
(?:
\s+
(?=
( # (2 start)
(?:
" [\S\s]*? "
| ' [\S\s]*? '
| (?:
(?! /> )
[^>]
)?
)+
) # (2 end)
)
\2
)?
\s* >
)
( [\S\s]*? ) # (3)
</ \1 \s* >
(?)
<
(样式)#(1),不可见内容;需要结束标记
(?:
\s+
(?=
(#(2开始)
(?:
“[\S\S]*?”
|“[\S\S]*?”
| (?:
(?! /> )
[^>]
)?
)+
)#(二完)
)
\2
)?
\s*>
)
([\S\S]*?)#(3)
如果有人对此感到好奇,则前瞻性断言将匹配其余的
样式标记内部attr/vals不仅专门进行验证,
但也要确保样式标签不是独立的(即使是打字错误)。
断言的内容是被动的,不受回溯的影响,
并且被捕获并插入刚刚经过断言的位置,其中回溯
环境是,但现在反向引用只是一个文字。
在像php这样的非JS环境中,这是通过替换
一个原子组(>..)
而不是断言。正则表达式的这部分([^>]*?)
告诉它介于
和
不允许包含
字符
[^>]
意味着不
,因此任何
都会弄乱您的选择,并在节点v14.13.1中运行以下结果:
[Running] /usr/bin/env node "...scratch/regex_test.js"
const regex = /<style[^>]*>([^>]*?)<\/style>/g
console.log(str1.match(regex))
console.log(str2.match(regex))
// output
[ '<style> div { color: red; } a { color: green; } </style>' ]
null // <-- NOT MATCHING!!!!!
我不知道你为什么不使用标准的“贪婪”量词而不是“懒惰”量词*?
。如果你不需要它,就不要使用它。这是一张关于你的备忘单
本要点中有一份代码副本:
正则表达式的这部分([^>]*?)
告诉它介于
和
不允许包含
字符
[^>]
意味着不
,因此任何
都会弄乱您的选择,并在节点v14.13.1中运行以下结果:
[Running] /usr/bin/env node "...scratch/regex_test.js"
const regex = /<style[^>]*>([^>]*?)<\/style>/g
console.log(str1.match(regex))
console.log(str2.match(regex))
// output
[ '<style> div { color: red; } a { color: green; } </style>' ]
null // <-- NOT MATCHING!!!!!
我不知道你为什么不使用标准的“贪婪”量词而不是“懒惰”量词*?
。如果你不需要它,就不要使用它。这是一张关于你的备忘单
本要点中有一份代码副本:
您应该将内容表达式更改为[\S\S]*?
,因为结束样式标记将是下一个html标记。这样的不可见内容需要一个结束标记。为什么不使用document.querySelector(“style”)
抓取元素呢?浏览器已经使用比正则表达式复杂得多的技术为您完成了解析工作,因此最好利用他们所有的辛苦工作,使用提供的API,而不是试图以临时方式进行解析。@ggorlen在我的特定用例中,我收到了一个HTML字符串,我没有访问DOM@Maxt