webentwicklung-frage-antwort-db.com.de

Vergleichen Sie eine Zeichenfolge mit mehreren Regex-Mustern

Ich habe eine Eingabezeichenfolge.

Ich denke, wie man diese Zeichenfolge effektiv gegen mehrere reguläre Ausdrücke anpasst.

Example Input: ABCD

Ich möchte mit diesen Reg-Ex-Mustern abgleichen und true zurückgeben, wenn mindestens eines davon übereinstimmt:

[a-zA-Z]{3}

^[^\\d].*

([\\w&&[^b]])*

Ich bin nicht sicher, wie ich mit mehreren Mustern gleichzeitig abgleichen kann. Kann mir jemand sagen, wie wir das effektiv machen?

17
Patan

Wenn Sie nur ein paar reguläre Ausdrücke haben, die alle zur Kompilierzeit bekannt sind, kann dies ausreichend sein:

private static final Pattern
  rx1 = Pattern.compile("..."),
  rx2 = Pattern.compile("..."),
  ...;

return rx1.matcher(s).matches() || rx2.matcher(s).matches() || ...;

Wenn weitere vorhanden sind oder zur Laufzeit geladen werden, verwenden Sie eine Liste mit Mustern:

final List<Pattern> rxs = new ArrayList<>();


for (Pattern rx : rxs) if (rx.matcher(input).matches()) return true;
return false;
22
Marko Topolnik

sie können einen großen Regex aus den einzelnen machen:

[a-zA-Z]{3}|^[^\\d].*|([\\w&&[^b]])*
19
vandale

Ich bin nicht sicher, was effectively bedeutet, aber wenn es um Leistung geht und Sie viele Zeichenketten prüfen möchten, würde ich dies tun

...
static Pattern p1 = Pattern.compile("[a-zA-Z]{3}");
static Pattern p2 = Pattern.compile("^[^\\d].*");
static Pattern p3 = Pattern.compile("([\\w&&[^b]])*");

public static boolean test(String s){
   return p1.matcher(s).matches ? true: 
        p2.matcher(s).matches ? true: 
        p3.matcher(s).matches;
}

Ich bin nicht sicher, wie sich dies auf die Leistung auswirkt, aber es könnte auch hilfreich sein, sie alle in einem einzigen Ausdruck mit | zu kombinieren.

1
NeplatnyUdaj

Um zu vermeiden, dass Instanzen von Pattern- und Matcher-Klassen neu erstellt werden, können Sie eine davon erstellen und wiederverwenden. Um die Matcher-Klasse wiederzuverwenden, können Sie die reset(newInput)-Methode verwenden. Warnung : Dieser Ansatz ist nicht threadsicher. Verwenden Sie es nur, wenn Sie garantieren können, dass nur ein Thread diese Methode verwenden kann. Erstellen Sie andernfalls für jeden Methodenaufruf eine separate Instanz von Matcher.

Dies ist eines der möglichen Codebeispiele

private static Matcher m1 = Pattern.compile("regex1").matcher("");
private static Matcher m2 = Pattern.compile("regex2").matcher("");
private static Matcher m3 = Pattern.compile("regex3").matcher("");

public boolean matchesAtLeastOneRegex(String input) {
    return     m1.reset(input).matches() 
            || m2.reset(input).matches()
            || m3.reset(input).matches();
}
1
Pshemo

Hier ist eine Alternative ..__ Beachten Sie, dass dies nicht in einer bestimmten Reihenfolge zurückgegeben wird. Dies könnte man aber tun, indem man beispielsweise nach m.start () sortiert.

private static HashMap<String, String> regs = new HashMap<String, String>();

...

    regs.put("COMMA", ",");
    regs.put("ID", "[a-z][a-zA-Z0-9]*");
    regs.put("SEMI", ";");
    regs.put("GETS", ":=");
    regs.put("DOT", "\\.");

    for (HashMap.Entry<String, String> entry : regs.entrySet()) {
        String key = entry.getKey();
        String value = entry.getValue();
        Matcher m = Pattern.compile(value).matcher("program var a, b, c; begin a := 0; end.");
        boolean f = m.find();
        while(f) 
        {
            System.out.println(key);
            System.out.print(m.group() + " ");
            System.out.print(m.start() + " ");
            System.out.println(m.end());
            f = m.find();
        }

    }   
}
0
NobodyReally

wie in ( Mehrere Regex-Muster in String ausführen ) ausgeführt, ist es besser, jeden Regex zu einem großen Regex zu verketten und nur den Matcher auszuführen. Dies ist eine große Verbesserung, wenn Sie den Regex häufig wiederverwenden. 

0
SkateScout