[英]Need help for writing regular expression
我在编写正则表达式方面无能为力,因此我将需要一些帮助。 我需要一个正则表达式,可以验证字符串是一组用逗号分隔的字母(字母必须是唯一的)。
只有一个字符,然后是逗号
例子:
A,E,R
R,A
E,R
谢谢
您可以使用重复的组来验证它是一个逗号分隔的字符串。
^[AER](?:,[AER])*$
要没有唯一字符,您可以执行以下操作:
^([AER])(?:,(?!\1)([AER])(?!.*\2))*$
如果我理解正确,那么有效的字符串将是两个字符模式的一系列(可能是零长),其中每个模式都是一个字母,后跟一个逗号; 最后最后写了一封信。
从而:
"^([A-Za-z],)*[A-Za-z]$"
编辑:由于您已经澄清了字母必须是A,E或R:
"^([AER],)*[AER]$"
像这样的"^([AER],)*[AER]$"
@Edit:关于唯一性,如果您可以放弃“最后一个字符不能是逗号”的要求(可以在正则表达式之前在固定时间内对其进行检查),那么这应该可以工作:
"^(?:([AER],?)(?!.*\\\\1))*$"
这将匹配A,E,R,
因此在执行正则表达式之前需要进行检查。 我对演出不承担任何责任,但是因为它只有3个字母...
上面显然是一个Java正则表达式,如果您想要一个“纯正的” ^(?:([AER],?)(?!.*\\1))*$
@ Edit2:很抱歉,错过了一件事:这实际上需要检查,然后您需要在末尾添加一个逗号,因为否则它也将匹配A,E,E
。 我知道有点有限。
我们对此正则表达式提出了一些建议:
^([AER],)*[AER]$
哪个确实有效。 然而,为了匹配字符串,它首先要备份一个字符,因为它会发现没有,
在年底。 因此我们为此进行切换以提高性能:
^[AER](,[AER])*$
请注意,这将在首次尝试时匹配正确的String。 但也请注意,我们完全不必担心( )*
备份; 它要么第一次匹配,要么根本不匹配String。 因此,我们可以使用所有格修饰符来进一步提高性能:
^[AER](,[AER])*+$
这将获取整个String并尝试匹配它。 如果失败,它将停止,通过不执行无用的备份来节省时间。
如果我试图确保String没有重复的元素,则不会使用regex; 它只会使事情复杂化。 您最终得到的代码可读性较低(可悲的是,大多数人不了解正则表达式),并且通常情况下,速度较慢。 因此,我将构建自己的验证器:
public static boolean isCommaDelimitedSet(String toValidate, HashSet<Character> toMatch) {
for (int index = 0; index < toValidate.length(); index++) {
if (index % 2 == 0) {
if (!toMatch.contains(toValidate.charAt(index))) return false;
} else {
if (toValidate.charAt(index) != ',') return false;
}
}
return true;
}
这假定您希望能够传递一组允许的字符。 如果您不希望这样并且具有要匹配的显式字符,请将if (index % 2 == 0)
块的内容更改为:
char c = toValidate.charAt(index);
if (c == 'A' || c == 'E' || c == 'R' || /* and so on */ ) return false;
我自己的丑陋但可扩展的解决方案,它将不允许使用逗号开头和结尾,并检查字符是否唯一。
它使用前向声明的反向引用:请注意第二个捕获组如何落后于对其进行的引用(?!.*\\2)
。 在第一次重复中,由于第二捕获组未捕获任何内容,因此Java将第二捕获组引用文本匹配的任何尝试都视为失败。
^([AER])(?!.*\1)(?:,(?!.*\2)([AER]))*+$
regex101上的演示 (在这种情况下,PCRE风味具有相同的行为)
测试用例:
A,E,R
A,R,E
E,R,A
A
R,E
R
E
A,
A,R,
A,A,R
E,A,E
A,E,E
X,R,E
R,A,E,
,A
AA,R,E
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.