我正在尝试解析以下字符串,类似于google对待搜索运算符的方式:
type1:words in key1 type2:word in key2 type3:key3
将组生成为键值对,例如
type1 -> words in key1
type2 -> word in key2
type3 -> key3
这是我到目前为止所得到的,但是比赛的结尾与下一对重叠,所以我只得到了第一组。
([\w\^]+):(.*?) \w+:
type1 -> words in key1
我觉得这应该通过反向引用来完成,但到目前为止我的尝试都失败了。什么是正确的方法?
答案 0 :(得分:3)
(\w+):([^:]*)(?=\s\w|$)
适用于所有样本数据。
(\w+) # Match a keyword
: # Match :
([^:]*) # Match as many non-colon characters as possible
(?= # Lookahead assertion: backtrack to
\s # the closest space
| # or
$ # don't backtrack at all if we're at the end of the string
) # End of lookahead
示例Python程序:
>>> import re
>>> r = re.compile(r"(\w+):([^:]*)(?=\s|$)")
>>> test = "type1:words in key1 type2:word in key2 type3:key3 type4:yet another key"
>>> for match in r.finditer(test):
... print("{} -> {}".format(match.group(1), match.group(2)))
...
type1 -> words in key1
type2 -> word in key2
type3 -> key3
type4 -> yet another key
答案 1 :(得分:1)
为避免吃下一部分的开头,请使正则表达式的最后\w+:
部分不消耗。这称为前瞻:
(?= re)通过零宽度正向前瞻(不消耗它)来匹配re。
所以你的正则表达式看起来像
([\w\^]+):(.*?) (?=\w+:|$)
答案 2 :(得分:0)
在模式上分割输入可能更容易
\s(?=\w+:\w)
或者,虽然它会颠倒匹配的顺序,但您可以从右到左进行评估并匹配
\w+:\w.*?
答案 3 :(得分:0)
我在php中的尝试:
preg_match_all( '/([\w\^]+?):(.+?)\s?(?=\w+:|$)/', 'type1:words in key1 type2:word in key2 type3:key3', $matches );
var_dump( $matches );
结果:
array(3) {
[0]=>
array(3) {
[0]=>
string(20) "type1:words in key1 "
[1]=>
string(19) "type2:word in key2 "
[2]=>
string(10) "type3:key3"
}
[1]=>
array(3) {
[0]=>
string(5) "type1"
[1]=>
string(5) "type2"
[2]=>
string(5) "type3"
}
[2]=>
array(3) {
[0]=>
string(13) "words in key1"
[1]=>
string(12) "word in key2"
[2]=>
string(4) "key3"
}
}