我知道这类问题已经被问过好几次了(例如这里或这里),但似乎我的问题不同,因为我找不到解决方案。
假设我得到这个字符串:
key=false hotel = trivago foo cool='tr ue' feels="good"
(注意每个空格都是故意放在那里的)
我打算提取每对值,例如key=false 就是其中之一。但是,如果一个词在一些可选空格后没有“=”,我打算返回 word = null。否则,这是相关的部分,如果单词在符号 ' 或 " 之间,我应该保存这些符号之间的任何内容。一个解释我的意思的例子: 上面的例子是为了返回这张地图:
{key=false, hotel=trivago, foo=null, cool=tr ue, feels=good}
我已经为上面的问题尝试了各种模式。就我想要的而言,我觉得最接近的是:
([a-zA-Z0-9]+)\s*[= ]+(?![^\"']*[\"'])
想法是:寻找其中包含数字的单词 ([a-zA-Z0-9]+),后跟可选数量的空格。然后寻找“=”。这部分不是真正的问题(我认为至少......) 问题是我想要的组(2):为了考虑像“东西”或“wo wsers”这样的例子,我查看了上面的链接并考虑使用负面前瞻。
我认为这正是我所需要的:group(2) 应该包含 = 符号之后的任何内容。如果有一个 ",添加字符串中的任何内容,直到我们到达下一个 "; '. 的交易相同。但是,如果没有提到的符号,请在下一个空格处停止。
我已经尝试了几个小时,但我不知道更多。谁能帮我?如果您还有其他问题,请随时提问!
编辑:因为我被要求提供更多的例子,这里是:
example with a lot of words. Makes=sense.
应该回来
{example=null, with=null, a=null, lot=null, of=null, words.=null, Makes=sense.}
另一个例子:
Did=you know that=I like= "cod ing"?
应该回来
{Did=you, know=null, that=I, like=cod ing?}
我们可以使用以下正则表达式匹配所有方法:
String input = "key=false hotel = trivago foo cool='tr ue' feels=\"good\"";
Map<String, String> map = new HashMap<>();
String regex = "(\\S+)\\s*=\\s*(?:'(.*?)'|\"(.*?)\"|(\\S+))";
Pattern r = Pattern.compile(regex);
Matcher m = r.matcher(input);
while (m.find()) {
String value = m.group(2);
if (value == null) {
value = m.group(3) == null ? m.group(4) : m.group(3);
}
map.put(m.group(1), value);
}
System.out.println(map);
// {feels=good, cool=tr ue, hotel=trivago, key=false}
这里使用的正则表达式模式急切地试图在单引号或双引号中找到一个值。如果失败,它将值定义为任何连续的非空白字符组 (
\S+
)。