2013-05-15 67 views
4

一類的名字,我知道我的問題可能看起來像一重實現this question,但它不是
我想匹配內部的來自服務器作爲HTML文本類名使用JavsScript RegExp的模板並將其替換爲另一個類的名稱。 這裏的代碼是什麼樣子:正則表達式得到HTML

<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 
+0

我知道這是不是比DOM操作速度更快,但我從服務器獲取不是一個DOM文本我正在使用一個特殊的框架 –

+0

雖然把HTML轉換成DOM元素很容易;-) –

+0

@AymanJitan你對這個事實一無所知, HTML不規則,因此不適合正則表達式。請參閱http://htmlparsing.com/regexes.html。使用DOM顯然是最好的選擇。 – Bart

回答

4

使用正則表達式,這個模式應該爲你工作:

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 

注:
對於上述正則表達式的工作必須有一流的字符串內沒有'"
I.e. <div class="a 'b' c d"...不是匹配。

+0

這是一個全新的問題:)請編輯你的問題,以清楚地說明你正在嘗試實現什麼(我會更新我的答案)。 – gkalpak

+0

對不起,但這個正則表達式匹配整個元素,我在匹配類後 –

+0

答案更新:) – gkalpak

0

這可能不是你的解決方案,但如果你是不是使用完整的regex匹配時,你可以做(​​假設你的例子是代表你將要解析的數據) :

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 
+0

這個過分的技巧,使用這種方式拆分需要很多時間 –

1

正則表達式不適合解析HTML。 HTML不規則。

jQuery在這裏可以非常適合。

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

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

選擇器[class~="b"]將選擇具有包含單詞b一個class屬性的任何元件。最初的HTML包裝在div中,以使find方法正常工作。

+0

謝謝,但我沒有使用jQuery,我不願意使用dom操作 –

2

使用瀏覽器,你的優勢:

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爲替代。這裏

+0

+1不錯。唯一的缺點是IE <9不支持'getElementsByClassName'。 – Bart

+0

@Bart不支持什麼?哦,你的意思是'getElementsByClassName'? –

+0

這可以是完美的解決方案,但不適合我的情況。 我將html注入到頁面之前對html進行了一些更改,並且dom在我正在使用的框架中無法幫助我。 –

1

測試: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}`); 
 
    }); 
 
}