我有正則運算式:
const regex = /^\d*\.?\d{0,2}$/
及其倒數(我相信)
const inverse = /^(?!\d*\.?\d{0,2}$)/
第一個正則運算式驗證字串是否適合任何正數,允許一個十進制數和兩個十進制數(例如150, 14., 7.4, 12.68)。第二個正則運算式是第一個正則運算式的逆,并且做一些測驗我相當有信心它給出了預期的結果,因為它只驗證字串不是一個可能有小數和兩位數的數字(例如12..05,)。a554.357
我的目標是從字串中洗掉任何不適合第一個正則運算式的字符。我以為我可以這樣做:
let myString = '123M.45';
let fixed = myString.replace(inverse, '');
但這不能按預期作業。為了除錯,我嘗試將替換字符更改為我可以看到的內容:
let fixed = myString.replace(inverse, 'ZZZ');
當我這樣做時,fixed變成:ZZZ123M.45
任何幫助將不勝感激。
uj5u.com熱心網友回復:
我想我理解你的邏輯,試圖找到一個與你的有效字串匹配的正則運算式的逆正則運算式,希望它允許你洗掉任何使你的字串無效的字符,只留下有效的字串。但是,我認為replace()不會允許您以這種方式解決您的問題。來自MDN 檔案:
replace()方法回傳一個新字串,其中模式的部分或全部匹配被替換替換。
在您的inverse模式中,您使用的是負前瞻。如果我們舉一個簡單的例子,X(?!Y)我們可以將其視為“如果沒有跟隨 Y,則匹配 X”。在您的模式中,您的“X”是^,您的“Y”是\d*\.?\d{0,2}$。根據我的理解,您得到的原因ZZZ123M.45是它找到了^您的模式未遵循的第一個(即字串的開頭)\d*\.?\d{0,2}$,并且由于123M.45與您的“Y”模式不匹配,因此您的負前瞻是滿意的并且字串的開頭與 ZZZ 匹配并“替換”。
那(我認為)是對您所看到的內容的解釋。
我會為您的問題提出一種替代解決方案,該解決方案更符合我對該.replace()方法的理解。而不是你的inverse模式,試試這個:
const invalidChars = /[^\d\.]|\.(?=\.)|(?<=\.\d\d)\d*/g
const myString = '123M..456444';
const fixed = myString.replace(invalidChars, '');
在這里,我使用了一種我認為將匹配您要洗掉的單個字符的模式。讓我們分解一下這個人在做什么:
[^\d\.]: 匹配非數字字符
\.(?=\.): 匹配.字符,如果它后面跟著另一個.字符。
(?<=\.\d\d)\d*: 匹配前面有小數點和 2 位數字的數字
然后我將所有這些與 ORs ( |) 連接起來,這樣它就會匹配上述任何一種模式,我使用g標志來替換所有匹配項,而不僅僅是第一個匹配項。
我不確定這是否會涵蓋您的所有用例,但我想我會試一試。這是一個可能比我的更有用的細分鏈接,如有必要,您可以使用此工具調整模式。
uj5u.com熱心網友回復:
我不認為你能做到這一點
從字串中洗掉任何不適合第一個正則運算式的字符
因為正則運算式匹配適用于整個字串,并且replace僅用于替換該字串中的一部分。所以里面的正則運算式replace必須是一個正則運算式,只匹配不需要的字符,而不是反轉的正則運算式。
您可以做的是使用原始字串驗證字串regex,然后如果它無效,請替換并再次驗證。
//if (notValid), replace unwanted character
// replace everything that's not a dot or digit
const replaceRegex = /[^\d.]/g; // notice g flag here to match every occurrence
const myString = '123M.45';
const fixed = myString.replace(replaceRegex, '');
console.log(fixed)
// validate again
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/432358.html
標籤:javascript 正则表达式
下一篇:無順序地將元素串列與字串匹配
