正则表达式提取由空格分隔的键值对,其值为空格
假设一个单行字符串具有多个连续的键值对,由空格分隔,但允许的值也在值内(不在键中),例如
key1=one two three key2=four key3=five six key4=seven eight nine ten
从上面正确提取键值对将产生以下映射:
"key1", "one two" "key2", "four" "key3", "five six" "key4", "seven eight nine ten"
其中“keyX”可以是任何字符序列,不包括空格。
尝试一些简单的事情,比如
([^=]+=[^=]+)+
或类似的变化是不够的。
是否有正则表达式来完全处理这样的提取,没有任何进一步的字符串处理?
尝试前瞻 :
(\b\w+)=(.*?(?=\s\w+=|$))
作为Java字符串:
"(\\b\\w+)=(.*?(?=\\s\\w+=|$))"
在regex101.com进行测试 ; 在regexplanet上测试 (点击“Java”)
\1
包含键和\2
值:
(key\d+)=(.*?)(?= key\d+|$)
在Java中使用\\
转义\
:
(key\\d+)=(.*?)(?= key\\d+|$)
演示: https : //regex101.com/r/dO8kM2/1
而不是正则表达式,我建议你使用indexOf
解析它。 就像是,
String in = "key1=one two three key2=four key3=five six " + "key4=seven eight nine ten"; Map kvp = new LinkedHashMap<>(); int prev = 0; int start; while ((start = in.indexOf("key", prev)) != -1) { // Find the next "=" sign. int eqlIndex = in.indexOf("=", start + 3); // Find the end... maybe the end of the String. int end = in.indexOf("key", eqlIndex + 1); if (end == -1) { // It's the end of the String. end = in.length(); } else { // One less than the next "key" end--; } kvp.put(in.substring(start, eqlIndex), in.substring(eqlIndex + 1, end).trim()); prev = start + 3; } for (String key : kvp.keySet()) { System.out.printf("%s=\"%s\"%n", key, kvp.get(key)); }
输出是
key1="one two three" key2="four" key3="five six" key4="seven eight nine ten"
如果没有重复空格,也可以这样:
([^\\s=]+)=([^=]+(?=\\s|$))
否则你总能写下这个:
([^\\s=]+)=([^=]+\\b(?=\\s|$))
如果关键名称不长,因为它们使用回溯,这些模式是一个很好的解决方案。
你也可以写这个最多需要一步回溯的东西:
([^\\s=]+)=(\\S+(?>\\s+[^=\\s]+)*(?!=))