3 回答

TA貢獻1875條經驗 獲得超3個贊
使用 2 個零寬度正向前瞻:
(?=.*?[a-zA-Z].*?[a-zA-Z]) Must contain 2 ASCII letters
(?=.*?[0-9].*?[0-9]) Must contain 2 digits
[a-zA-Z0-9]{8} Must be exactly 8 letters and/or digits
添加^和$如果不matches()用于運行正則表達式。
這意味著一個完整的正則表達式:
^(?=.*?[a-zA-Z].*?[a-zA-Z])(?=.*?[0-9].*?[0-9])[a-zA-Z0-9]{8}$
為獲得最佳性能,請將.模式替換為負字符類。在這種情況下,您可能希望使用重復的非捕獲組來縮短它:
(?=(?:[^a-zA-Z]*[a-zA-Z]){2})
(?=(?:[^0-9]*[0-9]){2})
更新
由于問題已更新為需要正則表達式用 * 替換此類單詞,應將錨點^和$錨點更改為\b單詞邊界模式,并且必須將負字符類更改為僅跳過有效字符:
s = s.replaceAll("\\b(?=(?:[0-9]*[a-zA-Z]){2})(?=(?:[a-zA-Z]*[0-9]){2})[a-zA-Z0-9]{8}\\b", "********");
有關演示,請參閱regex101。
請注意,vaff8loe在給定的示例中僅包含 1 個數字,因此不應替換。

TA貢獻1877條經驗 獲得超1個贊
您可以使用正向前瞻模式來限制數字和字母的數量:
\b(?=(?:\w*\d){2}\w*)(?=(?:\w*[A-Za-z]){2}\w*)\w{8}\b
演示:https : //regex101.com/r/z33bUv/7

TA貢獻1813條經驗 獲得超2個贊
在您需要將如此多的條件應用于解析的情況下(單詞必須具有長度 == 8、2+ 個字母字符、2+ 個數字字符且沒有特殊字符),我認為您應該努力尋找可以閱讀的解決方案而不是拋出單個復雜正則表達式中的所有內容。
假設您使用@Andreas解決方案,您的代碼將如下所示:
let s = "papave23 ciao il mio pin papaver1 è reeredji332ji con vaff8loe 1234567o 123t123t papavero 9o 123t123y";
s = s.replace(/\b(?=(?:[0-9]*[a-zA-Z]){2})(?=(?:[a-zA-Z]*[0-9]){2})[a-zA-Z0-9]{8}\b/g, "********");
console.log(s);
目前還不清楚您在這里做什么,最終的錯誤和/或邏輯更改將難以維護。相反,您可以利用函數替換參數來分解規則。然后你會有這樣的事情:
let s = "papave23 ciao il mio pin papaver1 è reeredji332ji con vaff8loe 1234567o 123t123t papavero 9o 123t123y";
// The first regex filters only 8-length words
s = s.replace(/\b\w{8}\b/g,
function(fullMatch) {
// .match() can return null if no match is found,
// so I'm accounting for this.
const digitMatch = fullMatch.match(/\d/g) || [];
const letterMatch = fullMatch.match(/[a-zA-Z]/g) || [];
const specialCharMatch = fullMatch.match(/\[^a-zA-Z0-9]/g);
if (digitMatch.length >= 2
&& letterMatch.length >= 2
&& specialCharMatch === null) {
return "********";
} else {
return fullMatch;
}
});
console.log(s);
它更冗長,但也更具可讀性和可調試性。
添加回答
舉報