我必须详细说明一个与字符串匹配的正则表达式,并具有以下限制:
foo
/foo
bar
我想出了以下模式,但我很确定有更优雅和/或更有效的解决方案:
String match = "quxfoobar";
String notMatch = "qux/foobar";
String notMatch2 = "fooquxbar";
String pattern = "(?!foo)(?!.+/foo).*bar";
boolean m = match.matches(pattern);
感谢您的投入。
注意:请注意我使用Java String.matches()
方法将我的模式与我的候选字符串相匹配。
答案 0 :(得分:3)
为何选择正则表达式?对于固定字符串,已经有内置函数,它应该比正则表达式方法快得多。
if (!str.startsWith("foo") && str.endsWith("bar") && !str.contains("/foo")) {
// Do your stuff here
}
答案 1 :(得分:0)
这个也可以满足你的需求:
^(?!foo)(/(?!foo)|[^/])*bar$
^(?!foo)
:字符串的开头后面不能跟foo
(/(?!foo)|[^/])*
:/
未跟foo
,或任何字符/
, n 次bar$
:字符串必须以bar
但经过一些测试后,你的速度比我快。由于我无法看到基于正则表达式的任何其他相关解决方案,我猜你的最终优雅和/或高效一个;)
答案 2 :(得分:0)
正则表达式的表现越差越好,越复杂。对于类似这样的事情,它应该更好地执行并且更容易理解以匹配三个正则表达式的输入。
String match = "quxfoobar";
Pattern start = Pattern.compile("^foo");
Pattern contain = Pattern.compile("\\/foo");
Pattern end = Pattern.compile("bar$");
boolean m = (
!start.matcher(match).find() &&
!contain.matcher(match).find() &&
end.matcher(match).find()
);
编辑:由于在这种情况下三个正则表达式是否会更快存在一些问题,我写了一个基准。当我运行它时,单个正则表达式(取自另一个答案)的速度是使用三个独立正则表达式运行的三倍。
import java.util.regex.*;
import java.util.*;
public class Test {
private static final Pattern START = Pattern.compile("^foo");
private static final Pattern CONTAIN = Pattern.compile("\\/foo");
private static final Pattern END = Pattern.compile("bar$");
private static final Pattern ONEPATTERN = Pattern.compile("^(?!foo)(\\/(?!foo)|[^\\/])*bar$");
public static void main(String[] args){
String[] in = createInput();
timeOnePattern(in);
timeThreePatterns(in);
System.exit(0);
}
public static String[] createInput(){
String[] words = {"foo","bar","baz","biz","/foo"};
Random rand = new Random();
String[] in = new String[10000];
for (int i=0; i<in.length; i++){
StringBuilder sb = new StringBuilder();
for (int j=0; j<4; j++){
sb.append(words[rand.nextInt(words.length)]);
}
in[i] = sb.toString();
}
return in;
}
public static void timeThreePatterns(String[] in){
long startTime = System.nanoTime();
for (String s: in){
boolean b = (!START.matcher(s).find() && !CONTAIN.matcher(s).find() && END.matcher(s).find());
}
long endTime = System.nanoTime();
System.out.println("Three regular expressionv took " + (endTime - startTime) + " nanoseconds.");
}
public static void timeOnePattern(String[] in){
long startTime = System.nanoTime();
for (String s: in){
ONEPATTERN.matcher(s).matches();
}
long endTime = System.nanoTime();
System.out.println("Single regular expression took " + (endTime - startTime) + " nanoseconds.");
}
}