有一个关于Java中正则表达式匹配的问题。给定了一个定义长度的字符串。现在我想用一个匹配器来检查这个字符串中包含的每个字符是否都不同。例如(仅限长度为8的通道):
String a = "abcdefgz" -> pass String b = "aacdefgz" -> fail String c = "abcdefghz" -> fail
因此,匹配长度将简单地为:
"^[a-zA-Z]{8}$"
但是要让它在每个包含的char都必须是唯一的条件下工作是相当坚韧的。
9lowa7mx1#
这个匹配包含重复项的字符串。这基本上是你要找的内容的反向。
.*(.)+.*\1.*
如果合适的话,你可以选择与这个表达式 * 不匹配 * 的字符串。或者检查regex negative match来改进它。
bq9c1y662#
我有一个非常丑陋的方式来做这个使用regex。它使用已命名的捕获组(?<name>)、反向引用\k<name>和负前瞻Assert(?!)。
(?<name>)
\k<name>
(?!)
@Test public void testForNonRepeatedCharactersUsingRegex() { 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()); }
如果您可以不使用regex,那么一个更干净、更清晰的解决方案是:
@Test public void testForNonRepeatedCharactersUsingStreams() { Assertions.assertTrue(uniqueCharacterSequence("abcdefgh", 8)); Assertions.assertTrue(uniqueCharacterSequence("ABCDEFGH", 8)); Assertions.assertFalse(uniqueCharacterSequence("12345678", 8)); Assertions.assertFalse(uniqueCharacterSequence("abefgh", 8)); Assertions.assertFalse(uniqueCharacterSequence("", 8)); Assertions.assertFalse(uniqueCharacterSequence("abcdefga", 8)); Assertions.assertFalse(uniqueCharacterSequence("aaaabbbb", 8)); } private static boolean uniqueCharacterSequence(String s, int length) { return s.length() == length && s.codePoints().allMatch(Character::isLetter) && s.codePoints().distinct().count() == length; }
2条答案
按热度按时间9lowa7mx1#
这个匹配包含重复项的字符串。这基本上是你要找的内容的反向。
如果合适的话,你可以选择与这个表达式 * 不匹配 * 的字符串。或者检查regex negative match来改进它。
bq9c1y662#
我有一个非常丑陋的方式来做这个使用regex。
它使用已命名的捕获组
(?<name>)
、反向引用\k<name>
和负前瞻Assert(?!)
。如果您可以不使用regex,那么一个更干净、更清晰的解决方案是: