有一個關于 Java 中的正則運算式匹配的問題。給定的是一個具有定義長度的字串。現在我想用匹配器檢查該字串中包含的每個字符是否不同。
例如(僅通過長度 = 8):
String a = "abcdefgz" -> pass
String b = "aacdefgz" -> fail
String c = "abcdefghz" -> fail
所以匹配長度將只是:
"^[a-zA-Z]{8}$"
但是要讓它與每個包含的字符都必須是唯一的條件相結合是非常困難的。
uj5u.com熱心網友回復:
好吧,這個匹配包含重復項的字串。這基本上與您正在尋找的相反。
.*(.) .*\1.*
如果合適,您可以選擇與此運算式不匹配的字串。或者也許檢查正則運算式否定匹配來改進它。
uj5u.com熱心網友回復:
我有一個非常丑陋的方式來使用正則運算式來做到這一點。
它使用命名的捕獲組(?<name>)、反向參考\k<name>和否定的前瞻斷言(?!)。
@Test
public void testForNonRepeatedLettersUsingRegex() {
Pattern p = Pattern.compile("^(?<c1>[a-zA-Z])(?!.*\\k<c1>)"
"(?<c3>[a-zA-Z])(?!.*\\k<c3>)"
"(?<c2>[a-zA-Z])(?!.*\\k<c2>)"
"(?<c4>[a-zA-Z])(?!.*\\k<c4>)"
"(?<c5>[a-zA-Z])(?!.*\\k<c5>)"
"(?<c6>[a-zA-Z])(?!.*\\k<c6>)"
"(?<c7>[a-zA-Z])(?!.*\\k<c7>)"
".$");
Assertions.assertTrue(p.matcher("abcdefgh").matches());
Assertions.assertTrue(p.matcher("ABCDEFGH").matches());
Assertions.assertFalse(p.matcher("12345678").matches());
Assertions.assertFalse(p.matcher("abefgh").matches());
Assertions.assertFalse(p.matcher("").matches());
Assertions.assertFalse(p.matcher("abcdefga").matches());
Assertions.assertFalse(p.matcher("aaaabbbb").matches());
}
如果您不能使用正則運算式,那么一個更清晰、更易讀的解決方案是:
@Test
public void testForNonRepeatedLettersUsingStreams() {
Assertions.assertTrue(uniqueLetter("abcdefgh", 8));
Assertions.assertTrue(uniqueLetter("ABCDEFGH", 8));
Assertions.assertFalse(uniqueLetter("12345678", 8));
Assertions.assertFalse(uniqueLetter("abefgh", 8));
Assertions.assertFalse(uniqueLetter("", 8));
Assertions.assertFalse(uniqueLetter("abcdefga", 8));
Assertions.assertFalse(uniqueLetter("aaaabbbb", 8));
}
private static boolean uniqueLetter(String s, int length) {
return s.length() == length &&
s.codePoints().allMatch(Character::isLetter) &&
s.codePoints().distinct().count() == length;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/528907.html
標籤:爪哇正则表达式
下一篇:正則運算式模式不適用于2個字符?
