问题再现
假设在一段文本中,同时存在 <link ... href="https://a.b.c/x.css" />
和 <a class href="https://a.b.c/y">
两种类型的特征字符集,现在我需要匹配中 link
的部分并且提取出 href="
引号之间的部分,而不匹配中 <a
tag 的这一段 href="
链接,正则表达式应该怎么修改完善?
针对特征的基础正则表达式
特征 "a.b.c/x.css"
,
/(['"])((https?:)?(\/\/)?[0-9A-Za-z_\-]+(\.[0-9A-Za-z_\-]+)+\/.*?['"])/
测试 1 link 字符串
/(['"])((https?:)?(\/\/)?[0-9A-Za-z_\-]+(\.[0-9A-Za-z_\-]+)+\/.*?['"])/.test(`<link href="https://a.b.c/x.css" />`)
返回为 true
测试 2 a 字符串
/(['"])((https?:)?(\/\/)?[0-9A-Za-z_\-]+(\.[0-9A-Za-z_\-]+)+\/.*?['"])/.test(`<a class href="https://a.b.c/y">`)
同样返回为 true
在基础正则表达式之上,完善对 a 字符串类型匹配的否定
利用 (?<!pattern)
来定义基础匹配之前字符的否定 pattern,定义在基础正则表达式之前。
否定特征 <a ... href=
,
/((?<!<a.+?href\s?=\s?)['"])((https?:)?(\/\/)?[0-9A-Za-z_\-]+(\.[0-9A-Za-z_\-]+)+\/.*?['"])/
测试 1 link 字符串
/((?<!<a.+?href\s?=\s?)['"])((https?:)?(\/\/)?[0-9A-Za-z_\-]+(\.[0-9A-Za-z_\-]+)+\/.*?['"])/.test(`<link href="https://a.b.c/x.css" />`)
返回为 true
测试 2 a 字符串
/((?<!<a.+?href\s?=\s?)['"])((https?:)?(\/\/)?[0-9A-Za-z_\-]+(\.[0-9A-Za-z_\-]+)+\/.*?['"])/.test(`<a class href="https://a.b.c/y">`)
返回为 false
总结
最终利用 (?<!pattern)
表达式在基础正则表达式的上面定义了排除 a 字符串类型的规则。