繁体   English   中英

需要帮助来编写正则表达式

[英]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风味具有相同的行为)

RegexPlanet上的演示

测试用例:

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM