1

我必须详细说明一个应该与具有以下限制的字符串匹配的正则表达式:

  • 字符串不能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()方法来匹配我的模式与我的候选字符串。

4

3 回答 3

3

为什么是正则表达式?对于固定字符串,已经有内置函数,应该比正则表达式方法快得多。

if (!str.startsWith("foo") && str.endsWith("bar") && !str.contains("/foo")) {
    // Do your stuff here
}
于 2013-02-06T17:58:44.817 回答
0

这个也可以满足您的需求:

^(?!foo)(/(?!foo)|[^/])*bar$
  • ^(?!foo): 字符串的开头不能跟foo
  • (/(?!foo)|[^/])*: 要么 a/后面没有foo, 要么任何字符但 a /, n
  • bar$: 字符串必须以bar

演示

但是经过一些测试,你的比我的快。由于我看不到任何其他基于正则表达式的相关解决方案,我猜你的最终是最优雅和/或最有效的解决方案;)

于 2013-02-06T17:13:01.190 回答
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.");
    }
}
于 2013-02-06T17:14:09.717 回答