正则表达式也有某些字母和至少一组字母

时间:2011-05-31 22:48:14

标签: java regex search letter

有人可以帮助我使用正则表达式声明来查找使用此规则的语句吗?

这个词需要有字母“J,U,G”(只是字母不是顺序)和至少其中一个字母:G,L,E,R,S

所以我可以搜索一下水壶,杂耍者,玩杂耍者,杂耍者等等。

由于

3 个答案:

答案 0 :(得分:2)

还有一个正则表达式解决方案。但是你应该真的给出你正在使用的语言,因为@Quick Joe Smith写道,可以为你的任务提供其他更好的解决方案。

^(?=.*J)(?=.*U)(?=.*G)(?=.*[LERS]).*$

Rubular

那些(?=)是正向前看,它们会检查字符串中是否有字符,但它们不匹配。最后的.*将匹配您的完整字符串。

您还需要修饰符i来启用ignorecase(不区分大小写)

答案 1 :(得分:0)

你问题的第一部分根本不适用于正则表达式。这种模式最终会导致复杂的混乱,只会在添加更多必需字符时变得更糟。

然而,第二部分是微不足道的:

m/[glers]/i

所以我建议分两部分实施解决方案。这取决于您的语言:

C#(使用Linq)

var chars = "GJU"; // characters are sorted.
if (inputstring.ToUpper().Intersect(chars).OrderBy(c => c).SequenceEqual(chars)) {
    // do stuff if match.
}

Perl(需要5.10)

my @chars = sort split '', 'GJU'; # Transform into sorted array.
my %input = map{($_, 1)} split '', uc $inputstring; # stores unique chars from string.
if (@chars ~~ %input) { # Smart match performs hash key intersection.
    # Do stuff in here.
}

的Python

chars = set('jug')
input = set(inputstring)
if chars == (chars & input):
    # do something here

答案 2 :(得分:0)

如果您一次只使用一个单词,请尝试以下操作:

boolean isMatch = s.matches(
  "(?i)^(?:J()|U()|G(?!.*G)()|[GLERS]()|\\w){4,}+$\\1\\2\\3\\4");

如果您要搜索较长字符串中的匹配项:

Pattern p = Pattern.compile(
    "(?i)\\b(?:J()|U()|G(?!.*G)()|[GLERS]()|\\w){4,}+\\b\\1\\2\\3\\4");
Matcher m = p.matcher(s);
while (m.find()) {
    String foundString = m.group();
} 

每当前四个备选方案中的一个 - J()U()G()[GLERS]()匹配某些内容时,其后面的空组就会“捕获”任何内容(即,一个空字符串)。当到达字符串的结尾时,每个后向引用 - \1\2等 - 尝试匹配其相应组匹配的相同内容:不再有任何内容。

显然,这将永远成功;你总能匹配注意到。诀窍在于,如果相应的组没有参与匹配,则反向引用甚至不会尝试匹配。也就是说,如果目标字符串中没有j,则()替代中的J()永远不会涉及。当正则表达式引擎稍后处理\1反向引用时,它会立即报告失败,因为它知道该组未参与该匹配。

通过这种方式,空组的作用就像一个复选框,反向引用确保已经检查了所有框。但是有一个皱纹。 G()[GLERS]()替代方案都可以匹配g;你如何确保他们在你需要时参加比赛?我试过的第一个正则表达式,

"(?i)^(?:J()|U()|G()|[GLERS]()|\\w){4,}+$\\1\\2\\3\\4"

...未能匹配“jugg”这个词,因为G()替代方案同时消耗了g个; [GLERS]()从未有机会参加。所以我添加了负面预测 - (?!.*G) - 现在它只匹配 last g。如果我有三个可以匹配g的替代方案,我必须将(?!.*G.*G)添加到第一个,(?!.*G)添加到第二个。{1}}。但实际上,在我达到这一点之前,我可能会切换到一种不同的方法(可能不涉及正则表达式)。 ;)