不以单词开头的字符串的正则表达式不包含另一个单词,但以第三个单词结尾

时间:2013-02-06 17:05:11

标签: java regex

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

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

3 个答案:

答案 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
  • 结尾

Demo

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

答案 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.");
    }
}