我有一个输入字符串。将字符串与多个正则表达式匹配
我想如何有效地将这个字符串与多个正则表达式进行匹配。
Example Input: ABCD
我想对阵这些REG-EX模式,并返回true
如果其中至少有一个匹配:
[a-zA-Z]{3}
^[^\\d].*
([\\w&&[^b]])*
我不知道如何来匹配多个模式一次。有人能告诉我我们如何有效地做到这一点?
我有一个输入字符串。将字符串与多个正则表达式匹配
我想如何有效地将这个字符串与多个正则表达式进行匹配。
Example Input: ABCD
我想对阵这些REG-EX模式,并返回true
如果其中至少有一个匹配:
[a-zA-Z]{3}
^[^\\d].*
([\\w&&[^b]])*
我不知道如何来匹配多个模式一次。有人能告诉我我们如何有效地做到这一点?
如果您只有几个正则表达式,它们都是已知的在编译的时候,这就足够了:
private static final Pattern
rx1 = Pattern.compile("..."),
rx2 = Pattern.compile("..."),
...;
return rx1.matcher(s).matches() || rx2.matcher(s).matches() || ...;
如果有更多的,或者他们被加载在运行时,然后使用一组模式:
final List<Pattern> rxs = new ArrayList<>();
for (Pattern rx : rxs) if (rx.matcher(input).matches()) return true;
return false;
我不知道什么effectively
手段,但如果它是关于性能,你想查了很多串,我会去为这个
...
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;
}
我不知道它将如何影响性能,但将它们与|
合并成一个正则表达式也可能有所帮助。
这重新逻辑or或缺少括号。为什么不使用'p1.matcher(s).matches()|| p2.matcher(s).matches()|| p3.matcher(s).matches()' – kratenko
你是对的。我不知道4年前我在想什么。 – NeplatnyUdaj
为了避免重新创建Pattern和Matcher类的实例,您可以创建其中的一个并重用它们。要重用Matcher
课程,您可以使用reset(newInput)
方法。 警告:此方法不是线程安全的。只有当你能保证只有一个线程能够使用这个方法时才使用它,否则为每个方法调用创建一个单独的Matcher实例。
这是可能的代码示例
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();
}
“Matcher”存在的全部目的是每次创建它以保持单个匹配动作的状态。你的代码不是线程安全的。 –
@MarkoTopolnik确实。感谢您指出了这一点。在一个线程环境中,重置Matcher似乎没有什么比重新创建它快,所以决定在我的答案中提到它。希望我的编辑能让我的回答更好。 – Pshemo
这是一个替代方案。 请注意,这不做的一件事是按特定顺序返回它们。但是可以通过以m.start()进行排序来实现。
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();
}
}
}
就像是在(Running multiple regex patterns on String)解释,最好是每个正则表达式串联到一个大的正则表达式,比运行匹配唯一的一个。这是一个很大的改进,你经常重用正则表达式。
你的问题不清楚(至少对我而言)。有效的意思是什么?你想检查输入是否匹配所有正则表达式,或者只有一个是足够的?你可以在输入期望的输出旁包含吗? – Pshemo
我认为,首先,你应该用自然语言来定义你想要匹配的字符序列。你的例子不让我们提取任何模式。或者,最好的是,这里的模式最符合您的输入:“ABCD”。 –
你想实现什么? – wumpz