即使在某些组不需要时仍然匹配,它们需要是可选的。
然后使用该Matcher#find()
方法以及Matcher#group(x)
访问组(从 1 开始,因为 0 是整个匹配项)。
例子:
String msg = "GET HTTP 200 OK"; //resource and protocol version are left out by purpose
Pattern pattern = Pattern.compile("(GET|get)?\\s(/[^\\s]*)?\\s(HTTP|http)?(/1\\.0)?");
Matcher matcher = pattern.matcher( msg );
while ( matcher.find() )
{
System.out.println(matcher.group( 1 )); //prints GET
System.out.println(matcher.group( 2 )); //prints null since there's no resource
System.out.println(matcher.group( 3 )); //prints HTTP
System.out.println(matcher.group( 4 )); //prints null since there's no version string
}
作为旁注,我需要稍微调整一下你的表情,因为第二组(/.*)
会贪婪地匹配第一个斜线之后的任何内容。不过,它仍然远非完美。
第二种方法可能是应用多个表达式/模式并将它们一个接一个地应用于匹配器。
例子:
Pattern methodPattern = Pattern.compile("GET|get");
Matcher matcher = methodPattern.matcher( msg );
if ( matcher.find() )
{
System.out.println("method: " + matcher.group());
}
if ( matcher.usePattern( Pattern.compile("\\s/([^\\s]*)") ).find() )
{
System.out.println("resource: " + matcher.group(1));
}
if ( matcher.usePattern( Pattern.compile("HTTP|http") ).find() )
{
System.out.println("protocol: " + matcher.group());
}
if ( matcher.usePattern( Pattern.compile("/(\\d\\.\\d)") ).find() )
{
System.out.println("version: " + matcher.group(1));
}
这使用了匹配器的读取位置设置为匹配后的位置的事实,并且任何后续调用find()
都将从那里开始。如果模式不匹配,则位置保持不变。
因此,这些模式必须按顺序应用,但是是可选的。