【问题标题】:Regular expression to get a class name from html从html中获取类名的正则表达式
【发布时间】:2013-05-09 16:16:20
【问题描述】:

我知道我的问题可能看起来像 this question 的重复,但它不是
我正在尝试使用 JavsScript RegExp 将来自服务器的 html text 中的类名作为模板匹配,并将其替换为另一个类名。 这是代码的样子:

<div class='a b c d'></div>
<!-- or -->
<div class="a b c d"></div>
<!-- There might be spaces after and before the = (the equal sign) -->

例如,我想匹配“b”类
以尽可能高的性能

这是我使用的正则表达式,但并非在所有情况下都有效,我不知道为什么:

  var key = 'b';
  statRegex = new RegExp('(<[\w+ class="[\\w\\s]*?)\\b('+key+')\\b([\\w\\s]*")');
  html.replace( statRegex,'SomeOtherClass');// I may be mistake by the way I am replacing it here

【问题讨论】:

  • 我知道它并不比 dom 操作快,但我从服务器而不是 dom 获取文本,并且我正在使用特殊框架
  • 将 HTML 转换为 DOM 元素很容易 ;-)
  • @AymanJitan 你不知道 HTML 不是正则的,因此不适合正则表达式。见htmlparsing.com/regexes.html。使用 DOM 显然是最好的方法。
  • @Bart 我有小部件,每个小部件由许多html模板组成,每个小部件内部都有不同状态的组件,状态由css类控制,我需要解析html并显示处于不同状态的组件和小部件。虽然很难解释。我知道 dom 快得多,但在我的情况下它不起作用
  • @AymanJitan 我可以想象这很复杂,但你错过了我想要表达的观点。这与速度无关。这是关于在现在和将来获得正确的结果。当 HTML 的格式发生变化时,正则表达式很可能会失败,因为 DOM 会为您提供可靠的结果。

标签: javascript regex performance


【解决方案1】:

这可能不是您的解决方案,但如果您没有设置使用完整的正则表达式匹配,您可以这样做(假设您的示例代表您将解析的数据) :

function hasTheClass(html_string, classname) {
    //!!~ turns -1 into false, and anything else into true. 
    return !!~html_string.split("=")[1].split(/[\'\"]/)[1].split(" ").indexOf(classname);
}

hasTheClass("<div class='a b c d'></div>", 'b'); //returns true

【讨论】:

  • 这有点矫枉过正,这样使用 split 会花费很多时间
【解决方案2】:

使用正则表达式,这个模式应该适合你:

var r = new RegExp("(<\\w+?\\s+?class\\s*=\\s*['\"][^'\"]*?\\b)" + key + "\\b", "i");
#                   Λ                                         Λ                  Λ
#                   |_________________________________________|                  |
#                           ____________|                                        |
# [Creating a backreference]                                                     |
# [which will be accessible]  [Using "i" makes the matching "case-insensitive".]_|
# [using $1 (see examples).]  [You can omit "i" for case-sensitive matching.   ]

例如

var oldClass = "b";
var newClass = "e";
var r = new RegExp("..." + oldClass + "...");

"<div class='a b c d'></div>".replace(r, "$1" + newClass);
    // ^-- returns: <div class='a e c d'></div>
"<div class=\"a b c d\"></div>".replace(r, "$1" + newClass);
    // ^-- returns: <div class="a e c d"></div>    
"<div class='abcd'></div>".replace(r, "$1" + newClass);
    // ^-- returns: <div class='abcd'></div>     // <-- NO change

注意:
要使上述正则表达式起作用,类字符串中必须没有 '"
IE。 &lt;div class="a 'b' c d"...匹配。

【讨论】:

  • 这是一个全新的问题 :) 请编辑您的问题以清楚说明您要达到的目标(我会更新我的答案)。
  • 对不起,这个正则表达式匹配整个元素,我只匹配类之后
【解决方案3】:

正则表达式不适合解析 HTML。 HTML 不规则。

jQuery 在这里非常适合。

var html = 'Your HTML here...';

$('<div>' + html + '</div>').find('[class~="b"]').each(function () {
    console.log(this);
});

选择器[class~="b"] 将选择具有包含单词bclass 属性的任何元素。初始 HTML 包装在 div 中,以使 find 方法正常工作。

【讨论】:

  • 谢谢,但我没有使用 jQuery,也不愿意使用 dom 操作
【解决方案4】:

充分利用浏览器:

var str = '<div class=\'a b c d\'></div>\
<!-- or -->\
<div class="a b c d"></div>\
<!-- There might be spaces after and before the = (the equal sign) -->';

var wrapper = document.createElement('div');
wrapper.innerHTML = str;

var elements = wrapper.getElementsByClassName('b');

if (elements.length) {
    // there are elements with class b
}

Demo

顺便说一句,getElementsByClassName() 在 IE 中直到版本 9 才得到很好的支持;检查this answer 以获取替代方案。

【讨论】:

  • +1 不错。唯一的缺点是 IE getElementsByClassName。
  • @Bart 到底不支持什么?哦,你是说getElementsByClassName
  • 这可能是完美的解决方案,但对我来说不是。在将 html 注入页面之前,我正在对 html 进行一些更改,并且 dom 不会在我正在使用的框架中帮助我。
  • @AymanJitan 那么在 DOM 中进行更改?目前还不清楚框架是如何阻止你这样做的。
  • @AymanJitan 进行更改并获取wrapper.innerHTML。没有比这更简单的了。
【解决方案5】:

在这里测试:https://regex101.com/r/vnOFjm/1

正则表达式:(?:class|className)=(?:["']\W+\s*(?:\w+)\()?["']([^'"]+)['"]

const regex = /(?:class|className)=(?:["']\W+\s*(?:\w+)\()?["']([^'"]+)['"]/gmi;
const str = `<div id="content" class="container">

<div style="overflow:hidden;margin-top:30px">
  <div style="width:300px;height:250px;float:left">
<ins class="adsbygoogle turbo" style="display:inline-block !important;width:300px;min-height:250px; display: none !important;" data-ad-client="ca-pub-1904398025977193" data-ad-slot="4723729075" data-color-link="2244BB" qgdsrhu="" hidden=""></ins>


<img src="http://static.teleman.pl/images/pixel.gif?show,753804,20160812" alt="" width="0" height="0" hidden="" style="display: none !important;">
</div>`;

let m;

while ((m = regex.exec(str)) !== null) {
    // This is necessary to avoid infinite loops with zero-width matches
    if (m.index === regex.lastIndex) {
        regex.lastIndex++;
    }
    
    // The result can be accessed through the `m`-variable.
    m.forEach((match, groupIndex) => {
        console.log(`Found match, group ${groupIndex}: ${match}`);
    });
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-21
    相关资源
    最近更新 更多