排坑·IPhone&IOS中不兼容正則中的斷言匹配


閱文時長 | 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即可。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM