J'ai une chaîne d'entrée.
Je pense comment faire correspondre cette chaîne à plus d'une expression régulière de manière efficace.
Example Input: ABCD
J'aimerais faire correspondre ces modèles de rég-ex et renvoyer true
si au moins l'un d'eux correspond:
[a-zA-Z]{3}
^[^\\d].*
([\\w&&[^b]])*
Je ne suis pas sûr de savoir comment faire correspondre plusieurs modèles à la fois. Quelqu'un peut-il me dire comment nous le faisons efficacement?
Si vous n’avez que quelques regex et qu’ils sont tous connus au moment de la compilation, cela peut suffire:
private static final Pattern
rx1 = Pattern.compile("..."),
rx2 = Pattern.compile("..."),
...;
return rx1.matcher(s).matches() || rx2.matcher(s).matches() || ...;
S'il y en a plus, ou s'ils sont chargés au moment de l'exécution, utilisez une liste de modèles:
final List<Pattern> rxs = new ArrayList<>();
for (Pattern rx : rxs) if (rx.matcher(input).matches()) return true;
return false;
vous pouvez créer un grand regex avec ceux-ci:
[a-zA-Z]{3}|^[^\\d].*|([\\w&&[^b]])*
Je ne suis pas sûr de ce que signifie effectively
, mais s'il s'agit de performances et que vous souhaitez vérifier beaucoup de chaînes, je m'attacherai à cela.
...
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;
}
Je ne sais pas comment cela affectera les performances, mais les combiner tous dans une expression rationnelle avec |
pourrait également aider.
Pour éviter de recréer des instances de classes Pattern et Matcher, vous pouvez en créer une et les réutiliser. Pour réutiliser la classe Matcher
, vous pouvez utiliser la méthode reset(newInput)
. Attention : Cette approche n’est pas thread-safe. Utilisez-la uniquement lorsque vous êtes certain qu'un seul thread pourra utiliser cette méthode. Sinon, créez une instance distincte de Matcher pour chaque appel de méthode.
C'est l'un des exemples de code possibles
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();
}
Voici une alternative ... Notez qu'une chose que cela ne fait pas est de les renvoyer dans un ordre spécifique Mais on pourrait le faire en triant par m.start () par exemple.
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();
}
}
}
comme cela a été expliqué dans ( Exécution de plusieurs modèles de regex sur String ), il est préférable de concaténer chaque regex en un grand regex et de n'exécuter qu'un seul matcher. C'est une grande amélioration si vous réutilisez souvent l'expression régulière.