作者banana2014 (香蕉共和国)
标题Re: [请益] 请问重复attr合并的正规法要如何写?
时间Sun Jul 23 14:13:01 2017
※ 引述《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」是取「Stick
y」的「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」功能雷同,在此不再赘述。
以上。
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 118.160.30.43
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/Web_Design/M.1500790383.A.432.html
※ 编辑: banana2014 (118.160.30.43), 07/23/2017 14:46:39
1F:推 CauseSam: 高手! 07/24 08:21
2F:推 maiico: 很详细 07/24 10:45
3F:推 ian90911: 推优文 07/24 10:48
4F:推 pk9058: 感谢大大的热心回复 :) 07/24 22:44
5F:→ pk9058: 目前小弟的写法是先用下面这段regex来取得attr group 07/24 22:46
6F:推 pk9058: style\s*=\s*['"]?([^'"]+)['"]?/ig 07/24 22:55
7F:→ pk9058: 之後将它删除,然後重建新的 style 07/24 22:56
8F:→ pk9058: 这是我自己写的正规表示法,如有错误希望大大可以指正小弟 07/24 22:58
10F:推 pk9058: 小弟熟读您的文章後又学到新的一课,感谢大大的细心教导 07/24 23:39