繁体   English   中英

python 中的字符串操作以提取特定字段

[英]string manipulation in python to extract specific fields

我在一个包含一些用户详细信息的文件中有一些数据,示例行如下

<User id="123" directoryId="122" userName="vik_username" lowerUserName="vik_username" active="1" createdDate="2013-12-01 08:25:34.451" updatedDate="2014-01-20 19:45:49.133" firstName="Vik" lowerFirstName="vik" lastName="GG" lowerLastName="gg" displayName="Vik GG" lowerDisplayName="vikgg" emailAddress="vikgg@vik.com" lowerEmailAddress="vikgg@vik.com">

我想在 python 中编写一个脚本并提取以下字段 1. 用户名 -- userName="vik_username" 2. email 地址 -- emailAddress="vikgg@vik.com" 3. 显示名称 -- displayName="Vik GG" 4.活跃状态——active="1"

我写了一个像这样的 python 脚本,我在 '" ' 上拆分双引号,后跟空格。

f = open("users.txt", "r")
user_array=[]
for x in f:
    y=x.split('" ')
    user_array.append(y)

这给了我一个名为 user_array 的数组,它将每个用户的详细信息作为一个数组。

print user_array[0]

返回

['<User id="123', 'directoryId="122', 'userName="vik_username', 'lowerUserName="vik_username', 'active="1', 'createdDate="2013-12-01 08:25:34.451', 'updatedDate="2014-01-20 19:45:49.133', 'firstName="Vik', 'lowerFirstName="vik', 'lastName="GG', 'lowerLastName="gg', 'displayName="Vik GG', 'lowerDisplayName="vikgg', 'emailAddress="vikgg@vik.com', 'lowerEmailAddress="vikgg@vik.com">\n']

现在获取我想要的字段 1. 用户名 -- userName="vik_username" 2. email 地址 -- emailAddress="vikgg@vik.com" 3. 显示名称 -- displayName="Vik GG" 4. 活动状态 --主动=“1”

我将不得不执行类似print(user_array[0][<<index of my field>>])之类的操作,然后再次拆分它以删除字段标签,例如userName="vik_username我需要删除userName="

有人可以帮助我在 python 中以更有效的方式做到这一点吗? 提前致谢。

您可以使用正则表达式:

import re

string = r'<User id="123" directoryId="122" userName="vik_username" lowerUserName="vik_username" active="1" createdDate="2013-12-01 08:25:34.451" updatedDate="2014-01-20 19:45:49.133" firstName="Vik" lowerFirstName="vik" lastName="GG" lowerLastName="gg" displayName="Vik GG" lowerDisplayName="vikgg" emailAddress="vikgg@vik.com" lowerEmailAddress="vikgg@vik.com">'
re.findall(r'\"(.*?)\"', string)

>>> ['123', '122', 'vik_username', 'vik_username', '1', '2013-12-01 08:25:34.451', '2014-01-20 19:45:49.133', 'Vik', 'vik', 'GG', 'gg', 'Vik GG', 'vikgg', 'vikgg@vik.com', 'vikgg@vik.com']

表达式\"(.*?)\"捕获 ( () ) 以引号 ( \" ) 开头和结尾且中间有 0 个或多个字符 ( .*? ) 的所有内容。

或者,如果您不想使用正则表达式,您可以执行类似string.split('\"')[1::2]的操作,在引号处拆分但跳过所有不需要的内容: [1::2] 位从列表 (1) 中的第二个项目开始每隔一个项目 (::2) 获取您。

然后您可以从返回值中获取您想要的任何项目。


使用 Jupyter 魔法进行快速性能检查:

%timeit -n 100000 string.split('\"')[1::2]
>>> 1.07 µs ± 40.7 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

%timeit -n 100000 re.findall(r'\"(.*?)\"', string)
>>> 4.65 µs ± 30.2 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

因此,如果这些微秒对您很重要,我实际上建议您切片而不是使用正则表达式。

import re
line = """<User id="123" directoryId="122" userName="vik_username" lowerUserName="vik_username" active="1" createdDate="2013-12-01 08:25:34.451" updatedDate="2014-01-20 19:45:49.133" firstName="Vik" lowerFirstName="vik" lastName="GG" lowerLastName="gg" displayName="Vik GG" lowerDisplayName="vikgg" emailAddress="vikgg@vik.com" lowerEmailAddress="vikgg@vik.com">"""

wanted_tags = ("userName", "emailAddress", "displayName", "active")
tag_contents = [re.search(fr'{tag}="(.*?)"', line).group(1) for tag in wanted_tags]
# ['vik_username', 'vikgg@vik.com', 'Vik GG', '1']

我们通过正则表达式匹配给定的标签及其内容。 您可以自定义wanted_tags并且生成的列表tag_contents具有这些wanted_tags的相应信息,按顺序排列。 如果你愿意,你可以用这 2 个做字典。

由于您的数据看起来像 XML 或其他标记,我建议您使用现成的解析器,例如lxml 如果向输入字符串添加结束标记(如果它不存在),您将能够将其解释为 XML:

from lxml import etree

s = '<User id="123" directoryId="122" userName="vik_username" lowerUserName="vik_username" active="1" createdDate="2013-12-01 08:25:34.451" updatedDate="2014-01-20 19:45:49.133" firstName="Vik" lowerFirstName="vik" lastName="GG" lowerLastName="gg" displayName="Vik GG" lowerDisplayName="vikgg" emailAddress="vikgg@vik.com" lowerEmailAddress="vikgg@vik.com">'
s +='</User>'
myxml = etree.fromstring(s)
d = myxml.attrib

print(d) # Dictionary for further processing
print(d.values()) # The list of values in a dictionary

我希望这有帮助!

编辑

Python 还内置了一个具有相同功能的xml模块:

import xml.etree.ElementTree as ET

s = '<User id="123" directoryId="122" userName="vik_username" lowerUserName="vik_username" active="1" createdDate="2013-12-01 08:25:34.451" updatedDate="2014-01-20 19:45:49.133" firstName="Vik" lowerFirstName="vik" lastName="GG" lowerLastName="gg" displayName="Vik GG" lowerDisplayName="vikgg" emailAddress="vikgg@vik.com" lowerEmailAddress="vikgg@vik.com">'
s +='</User>'
myxml = ET.fromstring(s)
d = myxml.attrib

print(d)
print(d.values())

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM