我们说我有一个字符串,我想检查它是否与任何可能的(随机)顺序中的另一个字符串匹配。例如,假设我有一个字符串s
,我想检查它是否与随机顺序中的"ONE"
匹配(==以下之一:ENO|EON|NEO|NOE|OEN|ONE
,但不是EEE;EEN;EEO;
等。)
在更一般的描述中:我正在寻找正则表达式以随机顺序匹配字符串,只有该字符串的给定字符(这意味着字符串本身可以包含重复字符,如{{1但是,应该在随机匹配中恰好使用两个SEVEN
,而不是更多或更少。)
我知道我可以使用文字E
来匹配ENO|EON|NEO|NOE|OEN|ONE
,ONE
到TWO
也一样,但这太长了..
我也知道我可以匹配所有内容,包括像NINE
这样的重复字符,但它也会错误地匹配[ONE]{3}
,EEE
等。
我知道我也可以创建一个循环来生成所有这些不同的排列,并将它们与EEN
分隔符一起追加。我认为在这种情况下,这也可能是一个有效的解决方案。但是,如果使用正则表达式这是可能的,我也想知道我自己的知识。哦,即使它有一个循环,我也不希望它太长(因为我实际上是因为代码 - 高尔夫挑战,你在哪里解决某个挑战在尽可能少的字节中。)
答案 0 :(得分:4)
你可以把条件放在前瞻性。对于ONE:
\b(?=\w*O)(?=\w*N)(?=\w*E)[ONE]{3}\b
对于SEVEN:
\b(?=\w*S)(?=\w*E\w*E)(?=\w*V)(?=\w*N)[SEVN]{5}\b
为了提高大文本的性能,您可以测试模式开头的字母和长度:
\b(?=[ONE]{3}\b)(?=\w*O)(?=\w*N)\w*E\w*
或:
\b(?=[SEVN]{5}\b)(?=\w*S)(?=\w*E\w*E)(?=\w*V)\w*N\w*
这样,包含其他字母或单词的单词不会很快被丢弃。
您还可以在最后设置效率较低的条件:
\b(?=[SEVN]{5}\b)(?=\w*S)(?=\w*V)(?=\w*N)\w*E\w*E\w*
要完成,您还可以使用否定的字符类来减少回溯:
\b(?=[SEVN]{5}\b)(?=[^\WS]*S)(?=[^\WV]*V)(?=[^\WN]*N)[^\WE]*E[^\WE]*E\w*
或使用其他字母:
\b(?=[SEVN]{5}\b)(?=[EVN]*S)(?=[SEN]*V)(?=[SEV]*N)[SVN]*E[SVN]*E\w*
答案 1 :(得分:1)
我认为,正则表达式不能这样做。
使用map< Integer,Integer>
来统计你的字符,并验证,或只是一个数组(更快)。
答案 2 :(得分:0)
是的,你可以构建你的正则表达式,使其像^(?=[ONE]{3}$)(?=.*O).*(?=.*N).*(?=.*E).*$
regex demo一样,所以你可以使用这样的东西:
public static void main(String[] args) {
String[] strings = new String[]{"ENOE", "ENO", "EON", "NEO", "NOE", "OEN",
"ONE", "OOO"};
Main m = new Main();
String word = "ONE";// This can be any word you want to matche
String regex = m.getPattern(word);
System.out.println(regex);
for (String s : strings) {
if (s.matches(regex)) {
System.out.println("matches : " + s);
} else {
System.out.println("Not matches : " + s);
}
}
}
// I use Java 8 to create the pattern it is more helpful
private String getPattern(String word) {
StringBuilder pattern = new StringBuilder();
//^(?=[ONE]{3}$)
pattern.append("^(?=[").append(word).append("]{").append(word.length()).append("}$)");
Arrays.asList(word.split("")).stream()
.map(t -> "(?=.*" + t + ").*")
.forEach(pattern::append);
pattern.append("$");
return pattern.toString();// result (?=.*O).*(?=.*N).*(?=.*E).*
}
<强>输出强>
Not matches : ENOE
matches : ENO
matches : EON
matches : NEO
matches : NOE
matches : OEN
matches : ONE
Not matches : OOO
答案 3 :(得分:0)
如果字符串中的字符是唯一的
,则可以使用以下正则表达式执行此操作<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>Foo</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>
您可以看到演示here
基本上它匹配一个3个字母的单词,由 [ONE] 中的字母组成,并确保所有3个单词出现在结果字符串中