閱文時長 | | 1.14分鍾 | 字數統計 | | 1834.4字符 |
主要內容 | | 1、問題切入 2、什么是斷言匹配 3、斷言匹配的替換方案 4、聲明與參考資料 | ||
『排坑·IPhone&IOS中不兼容正則中的斷言匹配』 | |||
編寫人 | | SCscHero | 編寫時間 | | 2020/12/7 AM12:14 |
文章類型 | | 單篇 | 完成度 | | 已完成 |
座右銘 | 每一個偉大的事業,都有一個微不足道的開始。 |
一、問題切入 完成度:100%
a) 問題發現
PC端谷歌、QQ、Edge瀏覽器正常運行,移動端安卓設備可以正常運行的正則。 Macbook沒有測試 (沒有Mac電腦) 。 在IPhone系設備,IOS系統中的Safari瀏覽器、QQ瀏覽器都出現報錯。報錯信息在JS中使用try..catch語句獲取到:SyntaxError:Invalid regular expression:invalid group specifier name。
b) 問題分析&排查方向
報錯分析:
報錯翻譯過來是"正則表達式無效:組說明符名稱無效。",推測是正則中的分組問題,然后經查其他使用正則的接口都是正常的,但出錯接口是因為含有斷言匹配。於是乎方向似乎明確了,IPhone設備可能將斷言匹配當做了普通分組,於是為了兼容IPhone設備,改用分組寫法匹配數據,詳見例子。
解決過程/排查方向/摸索過程(可跳過看下面解決方案):
【錯誤方向1】首先,由於在其他設備、系統中都可以正常運行。於是以為是CSS前綴問題,於是檢查了postcss-loader、autoprefixer插件。正常無問題。
【錯誤方向2】然后,檢查了下ES6語法是否轉換了ES5,檢查了babel配置,仍然沒問題。
【錯誤方向3】接着,想直接在IPhone機調試,發現無法調試。於是尋找可調試方案。
- 需要使用Macbook電腦,由於沒有硬件設備,於是尋找可替代方案。
- 使用windows系統模擬Safari網頁。此種方法需要安裝一大堆環境,由於擔心安裝過程中又出現一大堆坑,於是繼續尋找可替代方案。
- 於是使用異常捕獲,在出錯接口中彈出。捕獲了異常。
c) 解決方案
改寫斷言匹配的正則表達式內容,以其他正則表達式內容替代。詳見例子。
二、什么是斷言匹配 完成度:100%
a) 個人理解
斷言匹配是什么?斷言匹配是正則表達式中的一個概念。博主在Google了一下,沒有官方的定義,但在中文中基本叫斷言匹配。斷言匹配大致分為四種。詳見下文。
斷言匹配作用/用途?是正則表達式的條件語句。斷言匹配的原子組,不會被正常的分組。所以在匹配的時候,可以只匹配需要的部分。
b) 名詞普及
- (?!)零寬負向先行斷言
- (?=)零寬先行斷言
- (?<=)零寬后行斷言
- (?<!)零寬負向后行斷言。
c) 通俗解釋
- ?!后面不是什么
- ?=后面是什么
- ?<=前面是什么。
- ?<!前面不是什么
d) 詳細示例
下面本人使用JS的正則表達式的三個小例子來做示例。
{
//案例:替換除了pre標簽的其他標簽為p標簽。
let str = `
<h1>h1 label content</h1>
<pre>pre label content</pre>
<span>span label content</span>
`;
let reg = /<(?!pre)(.*?)>(?<content>[\s\S]+?)<\/\1>/g;
let repReg = str.replace(reg, "$<content>");
console.log(repReg);
}
{
//案例:將所有元前面數字統一加上.00;
let str = `
500,1000.00,1500
`;
let reg = /(\d+)(.00)?/g;
console.log(reg.exec(str));
//v,匹配值。args,詳細數組。
let res = str.replace(reg, (v, ...args) => {
console.log(args);
args[1] = args[1] || ".00";
return args.splice(0, 2).join("");
});
console.log(res);
}
{
//案例:匹配字母后面的數據
let str = "SCscHero123";
let reg = /(?<=SCscHero)\d+/i;
console.log(str.match(reg));
}
{//案例:匹配字符串中不能出現SC字母
let str = "SSSCscHero";
//即起始的后面,不能出現SC
console.log(str.match(/^(?!.*SC.*).*$/));
}
三、斷言匹配的替換方案 完成度:100%
斷言匹配的替換方案還是挺多的,主要目的就是分析字符串,達到你的目的即可(基本是廢話,手動滑稽)。下面用本人的一個例子講一下怎么處理。
【要求】從下面的字符串中提取需要的數字。
【分析】只需要提取數字,前后有固定的規律,因此符合使用斷言匹配的條件。同樣,也可以使用分組匹配提取其中的內容。
{//使用斷言匹配寫法
let str = "SCscHero123SCscHero";
let reg = /(?<=SCscHero)\d+(?=SCscHero)/g;
console.log(str.match(reg)[0]);
{//使用分組替換寫法
let str = "SCscHero123SCscHero";
let reg = /SCscHero(\d+)SCscHero/;
console.log(str.match(reg)[1]);
}
這只是個小例子哈,如果有其他問題解決不了的,請留言博客。讓博主也想想辦法,目前只能想到這個應用。
四、聲明與參考資料 完成度:100%
原創博文,未經許可請勿轉載。
如有幫助,歡迎點贊、收藏、關注。如有問題,請評論留言!如需與博主聯系的,直接博客私信SCscHero即可。