使用正则表达式如何全局查找多个子项呢?
最近群里有个同学提出了个问题,"kjdkfjdkkdjf_xkdfjkdhttp://www.xxx.com/news/th/123.htmlxxxxxkjdfdk"
一个正则怎么把 123 拿出来,123 可以是任何内容即可,有群友给出了个非常精简的 match
解决方案。
代码如下:
'dkfdf/a.html, dkfjkdjf/b.html'.match(/([^\/.]+)(?=\.html)/g) // 666 // => ["a", "b"]
正则表达式 – (?!), (?:), (?=) 使用方式可参考:https://www.cnblogs.com/allen2333/p/9835654.html
当然还有另外的群友给出了用 exec
的方案,参考引用:https://nosaid.com/article/regex-in-javascript#exec,代码如下:
const content = ` <script data-key="key1" src="1.js"></script> <script data-key="key2" src="2.js"></script> <script data-key="key3" src="3.js"></script> `; const reg = /data-key="(\S+?)"\s*src="(\S+?)"/g; let m; let matches = []; while ((m = reg.exec(content))) { matches.push(m); } console.log(matches); // output: // [ // ['data-key="key1" src="1.js"', 'key1', '1.js'], // ['data-key="key2" src="2.js"', 'key2', '2.js'], // ['data-key="key3" src="3.js"', 'key3', '3.js'] // ]
难度升级,如果是要把特征改为,必须是 news/th/123.html
即以 news/th/
开头呢?
可以使用 (?<=pattern)
非获取匹配,反向肯定预查,代码如下:
'www.xxx.com/news/th/a.html, www.yyy.com/news/th/b.html'.match(/(?<=news/th/)([^\/.]+)(?=\.html)/g) // => ["a", "b"]
【正则表达式】前瞻,后顾,负前瞻,负后顾
举个例子:
有个字符串
str = "博客园 顾客 博客 客园"
我们想匹配字符串里"博客园"的"客"字而不要其他的"客"字,这时就需要用到前瞻后顾。
正则表达式如下:
(?<=博)客(?=园)
反过来,我们不想要"博客园"的"客"字,但是想要其他"客"字。这时就要用到负前瞻,负后顾
正则表达式如下:
(?<!博)客(?!园)
总结一下:
前瞻: exp1(?=exp2)
查找 exp2 前面的 exp1
后顾: (?<=exp2)exp1
查找 exp2 后面的 exp1
负前瞻: exp1(?=exp2)
查找后面不是 exp2 的 exp1
负后顾: (?<=exp2)exp1
查找前面不是 exp2 的 exp1
可以发现,负前瞻、负后顾就是把前瞻、后顾中的"="改成了"!"
注意:后顾功能在大多数语言中有长度限制,只能使用定长的表达式,像 \w+
和 \d
这样的表达式长度可变,不能用在后顾中
一个复杂一点的例子:
str = "data: '|12 34 56 78 90|', data: '|12|3456|7890|', data: '|12|', data: '1234567890', data: '|1234|' "
我们要匹配 data 后面有 || 的部分,要求里面没有空格没有 | 并且长度大于 2
(?<=data: ')\|[^ \|]{2,}?\|(?=')
可以匹配到 |1234|