我有以下示例文本:
my_app|key1=value1|user_id=testuser|ip_address=10.10.10.10
我想通过以下方式提取其中的子字段:
appName = my_app,
[
{key = key1, value = value1},
{key = user_id, value = testuser},
{key = ip_address, value = 10.10.10.10}
]
为此,我编写了以下正则表达式:
(?<appName>\w+)\|(((?<key>\w+)?(?<equals>=)(?<value>[^\|]+))\|?)+
它匹配整个文本,但无法将其正确分组到命名组中。
我尝试在https://regex101.com/上测试它
这里我漏掉了什么?
发布于 2019-08-04 19:14:33
我认为您遇到的主要问题是试图编写一个匹配所有key=value对的正则表达式。这不是做这件事的方法。正确的方法是基于只与一个key=value
匹配的模式,但由查找该模式的所有精度的函数应用。每种语言都提供了这样的功能。以下是Python中的代码示例:
import re
txt = 'my_app|key1=value1|user_id=testuser|ip_address=10.10.10.10'
pairs = re.findall(r'(\w+)=([^|]+)', txt)
print(pairs)
这给出了:('key1','value1'),('user_id','testuser'),('ip_address','10.10.10.10')
该模式将由字母数字字符(\w+
)和值组成的键进行匹配。该值由([^|]+
)指定,这是除垂直线之外的所有值,因为该值可以具有非字母数字值,例如ip地址中的点。
注意findall
函数。有一个search
函数用于捕获一次模式,还有一个findall
函数用于捕获文本中的所有模式。我在regex101上测试了它,它起作用了。但是,我必须指出,您处理的特定文本模式不需要正则表达式。所有高级语言都提供了split
函数。你可以用垂直线分割,然后你得到的每个切片(第一个除外)再用等号分割。
发布于 2019-08-05 00:28:10
通过以下代码使用PyPi regex
module:
import regex
s = "my_app|key1=value1|user_id=testuser|ip_address=10.10.10.10"
rx = r"(?<appName>\w+)(?:\|(?<key>\w+)=(?<value>[^|]+))+"
print( [(m.group("appName"), dict(zip(m.captures("key"),m.captures("value")))) for m in regex.finditer(rx, s)] )
# => [('my_app', {'ip_address': '10.10.10.10', 'key1': 'value1', 'user_id': 'testuser'})]
.captures
属性包含在所有迭代中捕获到组中的所有值。
发布于 2019-08-05 00:42:22
不确定,但可能正则表达式可能不必要,拆分类似于,
data='my_app|key1=value1|user_id=testuser|ip_address=10.10.10.10'
x= data.split('|')
appName = []
for index,item in enumerate(x):
if index>0:
element = item.split('=')
temp = {"key":element[0],"value":element[1]}
appName.append(temp)
appName = str(x[0] + ',' + str(appName))
print(appName)
可能会返回与所需输出类似的输出:
my_app,[{'key': 'key1', 'value': 'value1'}, {'key': 'user_id', 'value': 'testuser'}, {'key': 'ip_address', 'value': '10.10.10.10'}]
使用dict
temp = {"key":element[0],"value":element[1]}
可以将temp
修改为您想要的其他数据结构。
https://stackoverflow.com/questions/57345942
复制相似问题