0

我正在尝试在 python 中解析以下两个字符串:

这是第一个字符串

s1="< one > < two > < three > here's one attribute < six : 10.3 > < seven : 8.5 > < eight : 90.1 > < nine : 8.7 >"

我需要一个 re 以便我可以将上面的内容拆分并存储在这样的列表中,其中下面新行中的每个项目都是列表中特定索引处的元素:

0 one    
1 two 
2 three
3 here's one attribute
4 six : 10.3
5 seven : 8.5
6 eight : 90.1
7 nine : 8.7

这是第二个字符串

s2="<one><two><three> an.attribute ::"

同样,我需要存储在这样的列表中的项目:

0 one
1 two
2 three
3 an.attribute

这是我到目前为止所尝试的,这是我从我在 Stack Overflow 上发布的另一个问题中得到的答案。

res = re.findall('< (.*?) >', s1)
pprint(res)
index=0
for index in res:
    print index

但这会跳过“这是一个属性”

输出:

['one', 'two', 'three', 'six : 10.3', 'seven : 8.5', 'eight : 90.1', 'nine : 8.7']
one
two
three
six : 10.3
seven : 8.5
eight : 90.1
nine : 8.7

谁能帮帮我?=)

如果有人知道如何从第一个字符串中提取 10.3、8.5、90.1 和 8.7 等字符串中的数值,那也太好了 =)

编辑:邓肯我试过你的代码,但我似乎没有得到我应该得到的输出。我假设我在某处犯了某种错误。你能告诉我它是什么吗?

from __future__ import generators
from pprint import pprint
s2="<one><two><three> an.attribute ::"
s1="< one > < two > < three > here's one attribute < six : 10.3 > < seven : 8.5 > <   eight : 90.1 > < nine : 8.7 >"
def parse(s):
    for t in s.split('<'):
        for u in t.strip().split('>',1):
            if u.strip(): yield u.strip()

list(parse(s1))
list(parse(s2))
pprint(s1)
pprint(s2)

这是我得到的输出:

"< one > < two > < three > here's one attribute < six : 10.3 > < seven : 8.5 > < eight : 90.1 > < nine : 8.7 >"
'<one><two><three> an.attribute ::'
4

2 回答 2

2

这得到了所有的东西,我相信你可以添加一些 if 语句和调整以获得所需的确切输出

c = 0
m=re.compile('< (\w+) (: ([\d.]+))* *> ([^<]*)')
for r in m.finditer(s1):
    c = c + 1
    (tag,junk,number,attribute)=r.groups()
    print c, attribute

编辑:更多解释

re.compile 行准备了一个正则表达式以供使用 要分解此正则表达式的作用,首先您必须了解 ( ) 圆括号标记最终将出现在结果中的项目 (r.groups())

所以表达式 < (\w+) 意味着找到一个 <,然后是一个空格,然后开始一个捕获组捕获组包含一个或多个“单词字符”,比如 a 到 z

这就是找到标签的方式

下一位是 (: ([\d.]+))* 再次启动一个捕获组,然后必须存在一个 : ,然后是另一个捕获组,它们被允许在彼此内部。方括号 [] 定义了一个字符类,而 \d 是数字的匹配项。这 。在这种情况下只是一个点!因此该类将匹配任何数字或点 + 表示“1 或多个前一个表达式”,因此它是一个或多个数字或点。这是为了得到号码。最后,在圆括号关闭捕获组之后,有一个星号 * 这意味着捕获前面表达式的零个或多个。这具有使前一组成为可选的效果。并非所有标签都有编号。

我将在那里停止对正则表达式的解释。有很多很好的资源可用于学习如何构建正则表达式

查找器只是在字符串上重复正则表达式并从中找到匹配项

该表达式(tag,junk,number,attribute)=r.groups()表示将列表结果(r.group)复制到各个变量标签、垃圾、数字和属性

于 2013-03-13T10:42:50.867 回答
1

这是一个根本不使用正则表达式的快速解决方案:

def parse(s):
    for t in s.split('<'):
        for u in t.strip().split('>',1):
            if u.strip(): yield u.strip()

>>> list(parse(s1))
['one', 'two', 'three', "here's one attribute", 'six : 10.3', 'seven : 8.5', 'eight : 90.1', 'nine : 8.7']
>>> list(parse("<one><two><three> an.attribute ::"))
['one', 'two', 'three', 'an.attribute ::']

>>> from pprint import pprint
>>> pprint(list(parse(s1)))
['one',
 'two',
 'three',
 "here's one attribute",
 'six : 10.3',
 'seven : 8.5',
 'eight : 90.1',
 'nine : 8.7']

你甚至可以把它写成一个单一的列表理解,但我不推荐它:

>>> [ u.strip() for t in s1.split('<') for u in t.strip().split('>',1) if u.strip() ]
['one', 'two', 'three', "here's one attribute", 'six : 10.3', 'seven : 8.5', 'eight : 90.1', 'nine : 8.7']
于 2013-03-13T12:14:41.957 回答