我有以下字符串
@name Home @options {} @include h1,h2,h3 @exclude p,div,em
我想通过正则表达式进行拆分并将其存储在HashMap
之类的
@name->Home
@options->{}
@include->h1,h2,h3
@exclude->p,div,em
我使用了以下正则表达式,但它在@name
之后匹配整个字符串import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class NewClass {
public static void main(String[] args) {
String regex = "((?<var>@(\\S)+) (?<val>.+) *)+";
String val = "@name Home @options {} @include h1,h2,h3 @exclude p,div,em";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(val);
if (matcher.matches()) {
System.out.println(matcher.group("var"));
System.out.println(matcher.group("val"));
}
}
}
输出为
@name
Home @options {} @include h1,h2,h3 @exclude p,div,em
答案 0 :(得分:2)
正则表达式的问题在于,您不知道输入中的组数,即有多少@xxx
组。因此,您需要多次应用正则表达式,即使用while循环和matcher.find()
:
while (matcher.find()) {
System.out.println(matcher.group("var"));
System.out.println(matcher.group("val"));
}
这就是说你的正则表达式只需要匹配一个组,并假设你之间没有任何其他东西,你基本上匹配从第一个@
到下一个或输入的结尾。因此,您的表达式可能会变为(?<var>@(\S)+) (?<val>[^@]+)
。
该表达式基本上包含2个部分,中间只有一个空格(您可能希望将其更改为\s+
:
(?<var>@(\S)+)
匹配以@
开头的组名称,并使用任何不是空格的内容进行恢复。请注意,此处不需要内部组,因此只需使用\S+
- 除非您想要在不使用@
的情况下提取名称。(?<val>[^@]+)
匹配至少一个不是@
的字符的任何序列,即下一个@
或输入结尾的任何字符。请注意,您不能以这种方式匹配空组,因此如果您想要匹配这些组,则可能需要将量词更改为*
。答案 1 :(得分:1)
使用(?<var>@\S+)\s+(?<val>\S+)
正则表达式而不是需要完整字符串匹配的.matches
,请使用while (matcher.find())
:
String regex = "(?<var>@\\S+)\\s+(?<val>\\S+)";
String val = "@name Home @options {} @include h1,h2,h3 @exclude p,div,em";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(val);
Map<String, String> m = new HashMap<String, String>();
while (matcher.find()) {
m.put(matcher.group("var"), matcher.group("val"));
}
System.out.println(m); // => {@name=Home, @exclude=p,div,em, @include=h1,h2,h3, @options={}}
请参阅Java demo
答案 2 :(得分:0)
答案 3 :(得分:0)
为什么要使用正则表达式?
只是说:只需拆分在“@”上的简单解析器可能会导致更易于理解代码。
这将导致数组“var value”;在那里,你只需将第一个空格后面的子字符串作为值。
你看 - 你需要其他人提出一个“正确的”正则表达式。这可能意味着每次想要增强/返工/更新该正则表达式时,您都必须转向其他人。