1

次の制限付きの文字列と一致する必要がある正規表現を作成する必要があります。

  • 文字列はで始まることはできませんfoo
  • 文字列には次のものを含めることはできません/foo
  • 文字列はで終わる必要がありますbar

私は次のパターンを思いついたが、もっとエレガントで効率的な解決策があると確信している。

String match = "quxfoobar";
String notMatch = "qux/foobar";
String notMatch2 = "fooquxbar";
String pattern = "(?!foo)(?!.+/foo).*bar";
boolean m = match.matches(pattern);

ご入力いただきありがとうございます。

注意:String.matches()パターンを候補の文字列と照合するメソッドでJavaを使用していることに注意してください。

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

正規表現は、長く複雑になるほどパフォーマンスが低下します。このような場合は、入力を3つの正規表現と照合する方が、パフォーマンスが高く、理解しやすいはずです。

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()
);

編集:この場合、3つの正規表現が高速になるかどうかについて疑問があるため、ベンチマークを作成しました。私がそれを実行すると、単一の正規表現(別の回答から取得)は、3つの別々の正規表現で実行する場合の3倍遅くなります。

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 に答える