Re: [请益] 请问重复attr合并的正规法要如何写?

楼主: banana2014 (香蕉共和国)   2017-07-23 14:13:01
※ 引述《pk9058 (WhenSunTea)》之铭言:
: 如标题
: regex:/(style[=]["](.*?)["]{2})/ig
: HTML内容:
: <div id="test" style="color:#FFF;" class="title_block" style="background:#000;" title="Hello">
: <span style="font-size:18pt;">标题</span>
: </div>
: 在 regexr.com 测试发现他会连同 h2 的style也包含...
: 麻烦版上的大大帮小弟解惑,谢谢
不晓得您的意思是不是要找同一个元素里的所有style标签
如果是,那有两种做法:
第一种作法比较简单
可以单纯只用一条Regex来找出“最后那个元素”的所有style标签
而且所有程式语言都通
Regex的pattern如下:
/(style=)('|\")[^'\"]*\2(?!(.|\n)*>(.|\n)*\1('|\")[^'\"]*\5)/gi
如下的程式码会匹配到红色字:
<div id="test" style="color:#FFF;" class="title_block" style="background:#000;" title="Hello" style="font-size:16px;">
<input style="font-size:18pt;" disabled style="color:red;" name="inp" style="text-align:left;">
<span style="color:#F00;" style="font-family:arial;">ABC</span>
</div>
<div style="text-decoration:none;" id="test2" style="color:blue">333</div>
我来说明一下这条pattern:
第一个桃红色部分的“(style=)”意思是匹配“style=”这个字串,这没什么学问。
第二个黄色部分的“('|\")[^'\"]*\2”意思是先匹配单引号(')或者双引号(")1次,然后后面可能有一个或多个不是单引号或双引号的字符,但也有可能没接,然后再接跟第2个括号里匹配的相同字符 (也就是如果你第一次输入双引号,这边就必须也是双引号,反之单引号亦然)
最后绿色部分的“(?!(.|\n)*>(.|\n)*\1('|\")[^'\"]*\5)”意思是这整个“style="..."”标签的后面不能有大于符号(>)然后又接着出现“style="..."”或“style='...'”的字样。
所以只要是最后一个元素的style标签就通通可以match得到。
第二种就比较复杂麻烦了,必须要配合程式来做才行,而且不见得所有浏览器都支援这种方法:
第二种就可以像你所说的匹配“第一个元素”的所有style标签
如果您是用Javascript写
Regex的pattern如下:
/[^>]*?(style=)('|\")[^'\"]*\2(?=[^>]*>[^>]*)/gyi
这里我们用到了新的modifier:“y”(在旧浏览器,如IE可能不支援)
我来说明一下这个“y”好了
“y”是取“Sticky”的“y”来作为这个modifier的名称
意思是:“只允许从开头开始的连续匹配(如果“g”被设定则会连续),连续处是从上一个匹配的字的结尾处开始”
例如:
/a/gy
这里我们只可以匹配所有连续且从开头开始的“a”
所以“aaassaaaa”只匹配到前三个“a”,后面的“a”则完全都匹配不到
另外像“mmmaaassaaaa”则所有的“a”都匹配不到。
回来上面的Regex pattern,
这行pattern的意思就是:如果“style="..."”或“style='...'”的前面都没有任何大于符号(>) ([^>]*?),且后面又有出现大于符号(>) ((?=[^>]*>[^>]*)),然后又从开头连续 (y modifier、g modifier),那么就匹配
所以像下面这段原始码会匹配到有底色的字:
<div id="test" style="color:#FFF;" class="title_block" style="background:#000;" title="Hello" style="font-size:16px;" alt="test" style="text-shadow:none;">
<span style="font-size:18pt;" title="test1" style="text-decoration:none;" id="test1" style="font-family:arial;">ABC</span>
<span style="color:blue;" style="font-weight:bold;">Hello!</span>
</div>
<div style="position:absolute;" class="test2" style="top:0;left:0;"></div>
但是这并不是我们要的结果,
我们只想要像“style="..."”这样的标签
所以就必须要用Javascript程式去撷取字串了。
程式如下:
var str = "(原始码...)";
var res = str.match(/[^>]*?(style=)('|\")[^'\"]*\2(?=[^>]*>[^>]*)/gyi);
var result = res.map(function(s){ return s.substr(s.indexOf("style=")); });
最后得到的阵列result就是我们想要的结果
◎ 其中这里的map就是对某一阵列一一做函数的处理。
如果您用第二种方法是用PHP写的,那么就把“y”改成“A”即可
“A”与“y”功能雷同,在此不再赘述。
以上。
作者: CauseSam (天翼)   2017-07-24 08:21:00
高手!
作者: maiico (ming)   2017-07-24 10:45:00
很详细
作者: ian90911 (xopowo)   2017-07-24 10:48:00
推优文
作者: pk9058 (WhenSunTea)   2017-07-24 22:44:00
感谢大大的热心回复 :)目前小弟的写法是先用下面这段regex来取得attr groupstyle\s*=\s*['"]?([^'"]+)['"]?/ig之后将它删除,然后重建新的 style这是我自己写的正规表示法,如有错误希望大大可以指正小弟https://codepen.io/anon/pen/oeNdRZ小弟熟读您的文章后又学到新的一课,感谢大大的细心教导

Links booklink

Contact Us: admin [ a t ] ucptt.com