我有一个输入字符串,它将遵循模式/user/<id>?name=<name>
,其中<id>
是字母数字,但必须以字母开头,而<name>
是一个只有字母的字符串,可以有多个空间。匹配的一些例子是:
/user/ad?name=a a
/user/one111?name=one ONE oNe
/user/hello?name=world
我想出了以下正则表达式:
String regex = "/user/[a-zA-Z]+\\w*\\?name=[a-zA-Z\\s]+";
以上所有示例都与正则表达式匹配,但它仅查看<name>
中的第一个单词。序列\s
不应该允许我有空格吗?
我为测试它正在做的事情所做的代码是:
String regex = "/user/[a-zA-Z]+\\w*\\?name=[a-zA-Z\\s]+";
// Check to see that input matches pattern
if(Pattern.matches(regex, str) == true){
str = str.replaceFirst("/user/", "");
str = str.replaceFirst("name=", "");
String[] tokens = str.split("\\?");
System.out.println("size = " + tokens.length);
System.out.println("tokens[0] = " + tokens[0]);
System.out.println("tokens[1] = " + tokens[1]);
} else
System.out.println("Didn't match.");
例如,一个测试可能看起来像:
/user/myID123?name=firstName LastName
size = 2
tokens[0] = myID123
tokens[1] = firstName
而期望的输出将是
tokens[1] = firstName LastName
如何更改我的正则表达式呢?
答案 0 :(得分:3)
不确定您认为代码中存在的问题。 <{1}} 确实在您的示例中包含tokens[1]
。
这是显示此内容的ideone.com demo。
但是,您是否考虑过使用捕获组来获取ID和名称。
如果你像
那样写firstName LastName
您可以抓住String regex = "/user/(\\w+)\\?name=([a-zA-Z\\s]+)";
Matcher m = Pattern.compile(regex).matcher(input);
和myID123
到firstName LastName
和m.group(1)
答案 1 :(得分:1)
我没有在您的代码中发现任何错误,但您可以捕获这样的组:
String str = "/user/myID123?name=firstName LastName ";
String regex = "/user/([a-zA-Z]+\\w*)\\?name=([a-zA-Z\\s]+)";
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(str);
if(m.find()) {
System.out.println(m.group(1) + ", " + m.group(2));
}
答案 2 :(得分:1)
问题是*
默认是贪婪的(它匹配整个字符串),所以你需要通过添加?
来修改你的正则表达式(使其不情愿):
List<String> str = Arrays.asList("/user/ad?name=a a", "/user/one111?name=one ONE oNe", "/user/hello?name=world");
String regex = "/user/([a-zA-Z]+\\w*?)\\?name=([a-zA-Z\\s]+)";
for (String s : str) {
Matcher matcher = Pattern.compile(regex).matcher(s);
if (matcher.matches()) {
System.out.println("user: " + matcher.group(1));
System.out.println("name: " + matcher.group(2));
}
}
输出:
user: ad
name: a a
user: one111
name: one ONE oNe
user: hello
name: world