我想编写一个函数,使我能够提取属性“ fmc”的值和“标签”部分中的文本。我想使用正则表达式解决方案。
<?xml version = "1.0" encoding="UTF-8" standalone="yes" ?>
<corpus>
<ver id="18" etude="EC1_Elec" elec="oui" niveau="1" critere="1.3" type="discours">
<part code="EC1_Elec_IW04_0">Ça existe sur des gros parcs Hlm mais c'est macro.</part>
</ver>
<ver id="30" etude="EC1_Elec" elec="oui" niveau="2" critere="" origine="IW" type="discours" fmc="motives">
<part code="EC1_Elec_IW01_0">Avant 75 on n'a pas isolé puis après, au fur et à mesure des règlementations.</part>
</ver>
<ver id="54" etude="EC1_Elec" elec="oui" niveau="1" critere="" origine="IW" type="discours" fmc="condition">
<part code="EC1_Elec_IW10_0">Le deuxième boitier, il est où ? s'il y en a un qui est à l'intérieur et qui remplace un bout de l'isolation, il est caché OK.</part>
</ver>
<ver id="897" etude="EC3_Elec" elec="oui" niveau="4" critere="4.1" origine="TR" type="discours" fmc="obstacle">
<part code="EC3_Elec_TR2_1">Avec l'économie d'énergie, on va imposer de plus en plus d'automatismes,</part>
<iwer>Çava influencer la demande pour ce type de solution c'est ça ?</iwer>
<part code="EC3_Elec_TR2_1">Je pense oui</part>
</ver>
</corpus>
所以我必须修改此功能以适合我的数据,但我不知道如何使用,因为如下所示,我将在以后使用它:
对于线标签,我有三个标签
def review(line, category='dvd', do_lower=False):
"""
Extract review and label
"""
m = re.search('(?<=<rating>)\d+.\d+(?=<\/rating>)', line)
label = 1 if int(float(m.group(0))) > 3 else 0 # rating == 3 are already removed
if category == 'dvd':
m = re.search('(?<=\/url><text>)(.|\n|\t|\f)+(?=\<\/title><summary>)', line)
else:
m = re.search('(?<=\/url><text>)(.|\n|\t|\f)+(?=\<\/text><title>)', line)
review_text = m.group(0)
if do_lower:
review_text = review_text.lower()
#return review_text, label
print(review_text, label)
def get_review(line, category='dvd', do_lower=False):
"""
Input: line
Returns cleaned review and label
"""
review_text, label = review(line, category=category, do_lower=do_lower)
review_text = cleaner(review_text, rm_new_lines=True)
return review_text, label
因此,对于我的示例,该函数应返回此值(在标签之前进行检查):
Label review_text
motivation Avant 75 on n'a pas isolé puis après, au fur et à mesure des règlementations.
condition Le deuxième boitier, il est où ? s'il y en a un qui est à l'intérieur et qui remplace un bout de l'isolation, il est caché OK.
obstacle Avec l'économie d'énergie, on va imposer de plus en plus d'automatismes,
obstacle Je pense oui
以便在此行代码中使用它:
categories = ['books', 'dvd', 'music']
lang = 'fr'
val_ratio = args.val_ratio
train_fname = 'train.tsv' if args.use_hugging_face else 'train_0.tsv'
val_fname = 'dev.tsv' if args.use_hugging_face else 'valid_0.tsv'
test_fname = 'test.tsv' if args.use_hugging_face else 'test_0.tsv'
for category in categories:
print('-'*20)
path = os.path.join(indir, lang, category)
sp = ['train', 'test']
for s in sp:
review_texts = []
labels = []
stats = []
with open(os.path.join(path, s+'.review'), 'rt', encoding='utf-8') as f_in:
next(f_in)
i = 0
text = f_in.read()
for line in text.split('\n\n'):
if len(line) > 9:
i += 1
review_text, label = get_review(line, category=category, do_lower=args.do_lower)
review_texts.append(review_text)
labels.append(label)
stats.append(len(review_text.split()))
尝试这个/fmc(.*?)+=(.*?)+\"(.+?)\"/g
您可以尝试正则表达式:
<([a-zA-Z0-9]+)[^\/]*?fmc=([\'\"])(.*?)\2.*?>[\s\n\r]*<([a-zA-Z0-9]+).*?>(.*?)</\4>
如图所示here。
完整的代码如下:
import re
f = """<corpus>
<ver id="18" etude="EC1_Elec" elec="oui" niveau="1" critere="1.3" type="discours">
<part code="EC1_Elec_IW04_0">Ça existe sur des gros parcs Hlm mais c'est macro.</part>
</ver>
<ver id="30" etude="EC1_Elec" elec="oui" niveau="2" critere="" origine="IW" type="discours" fmc="motivation">
<part code="EC1_Elec_IW01_0">Avant 75 on n'a pas isolé puis après, au fur et à mesure des règlementations.</part>
</ver>
<ver id="54" etude="EC1_Elec" elec="oui" niveau="1" critere="" origine="IW" type="discours" fmc="condition">
<part code="EC1_Elec_IW10_0">Le deuxième boitier, il est où ? s'il y en a un qui est à l'intérieur et qui remplace un bout de l'isolation, il est caché OK.</part>
</ver>
<ver id="897" etude="EC3_Elec" elec="oui" niveau="4" critere="4.1" origine="TR" type="discours">
<part code="EC3_Elec_TR2_1">Avec l'économie d'énergie, on va imposer de plus en plus d'automatismes,</part>
<iwer>Çava influencer la demande pour ce type de solution c'est ça ?</iwer>
<part code="EC3_Elec_TR2_1">Je pense oui</part>
</ver>
</corpus>"""
regex = r'<([a-zA-Z0-9]+)[^\/]*?fmc=([\'\"])(.*?)\2.*?>[\s\n\r]*<([a-zA-Z0-9]+).*?>(.*?)</\4>'
matches = re.findall(regex, f)
for x in matches:
print(x[2] + " " + x[4])
正则表达式确实是错误的解决方案,但这可能有效:
fmc="(.*?)".*?<part.*?>(.*?)</part>
https://regex101.com/r/M7LJLU/1
您想要的结果将在\1
和\2
中。
这是更适合XML解析器的工作。我使用untangle
资源库中的PyPI
:
import untangle
xml = """<?xml version = "1.0" encoding="UTF-8" standalone="yes" ?>
<corpus>
<ver id="18" etude="EC1_Elec" elec="oui" niveau="1" critere="1.3" type="discours">
<part code="EC1_Elec_IW04_0">Ça existe sur des gros parcs Hlm mais c'est macro.</part>
</ver>
<ver id="30" etude="EC1_Elec" elec="oui" niveau="2" critere="" origine="IW" type="discours" fmc="motives">
<part code="EC1_Elec_IW01_0">Avant 75 on n'a pas isolé puis après, au fur et à mesure des règlementations.</part>
</ver>
<ver id="54" etude="EC1_Elec" elec="oui" niveau="1" critere="" origine="IW" type="discours" fmc="condition">
<part code="EC1_Elec_IW10_0">Le deuxième boitier, il est où ? s'il y en a un qui est à l'intérieur et qui remplace un bout de l'isolation, il est caché OK.</part>
</ver>
<ver id="897" etude="EC3_Elec" elec="oui" niveau="4" critere="4.1" origine="TR" type="discours" fmc="obstacle">
<part code="EC3_Elec_TR2_1">Avec l'économie d'énergie, on va imposer de plus en plus d'automatismes,</part>
<iwer>Çava influencer la demande pour ce type de solution c'est ça ?</iwer>
<part code="EC3_Elec_TR2_1">Je pense oui</part>
</ver>
</corpus>
"""
doc = untangle.parse(xml)
for ver in doc.corpus.ver:
print(f"id={ver['id']}, fmc={ver['fmc']}")
for part in ver.part:
print(f" part={part.cdata}")
打印:
id=18, fmc=None
part=Ça existe sur des gros parcs Hlm mais c'est macro.
id=30, fmc=motives
part=Avant 75 on n'a pas isolé puis après, au fur et à mesure des règlementations.
id=54, fmc=condition
part=Le deuxième boitier, il est où ? s'il y en a un qui est à l'intérieur et qui remplace un bout de l'isolation, il est caché OK.
id=897, fmc=obstacle
part=Avec l'économie d'énergie, on va imposer de plus en plus d'automatismes,
part=Je pense oui
[我意识到您明确要求使用正则表达式解决方案,但作为替代方案,这里使用的是使用内置于xml解析器中的python之一,特别是xml.etree.ElementTree
。
xml.etree.ElementTree
输出为
xml_string = """<?xml version = "1.0" encoding="UTF-8" standalone="yes" ?>
<corpus>
<ver id="18" etude="EC1_Elec" elec="oui" niveau="1" critere="1.3" type="discours">
<part code="EC1_Elec_IW04_0">Ça existe sur des gros parcs Hlm mais c'est macro.</part>
</ver>
<ver id="30" etude="EC1_Elec" elec="oui" niveau="2" critere="" origine="IW" type="discours" fmc="motives">
<part code="EC1_Elec_IW01_0">Avant 75 on n'a pas isolé puis après, au fur et à mesure des règlementations.</part>
</ver>
<ver id="54" etude="EC1_Elec" elec="oui" niveau="1" critere="" origine="IW" type="discours" fmc="condition">
<part code="EC1_Elec_IW10_0">Le deuxième boitier, il est où ? s'il y en a un qui est à l'intérieur et qui remplace un bout de l'isolation, il est caché OK.</part>
</ver>
<ver id="897" etude="EC3_Elec" elec="oui" niveau="4" critere="4.1" origine="TR" type="discours" fmc="obstacle">
<part code="EC3_Elec_TR2_1">Avec l'économie d'énergie, on va imposer de plus en plus d'automatismes,</part>
<iwer>Çava influencer la demande pour ce type de solution c'est ça ?</iwer>
<part code="EC3_Elec_TR2_1">Je pense oui</part>
</ver>
</corpus>"""
import xml.etree.ElementTree as ET
tree = ET.fromstring(xml_string)
for i in tree.findall('ver'):
fmc = i.attrib.get("fmc")
if fmc is None:
continue
for p in i.findall("part"):
print(fmc, p.text)
如果要使用xpath表达式,则可以稍微简化一下
motives Avant 75 on n'a pas isolé puis après, au fur et à mesure des règlementations.
condition Le deuxième boitier, il est où ? s'il y en a un qui est à l'intérieur et qui remplace un bout de l'isolation, il est caché OK.
obstacle Avec l'économie d'énergie, on va imposer de plus en plus d'automatismes,
obstacle Je pense oui
为什么不使用for i in tree.findall('ver[@fmc]'):
for p in i.findall('part'):
print(i.attrib['fmc'], p.text)
解析XML?恕我直言,让lxml解析xml并使用例如导航到结果元素树要容易得多。 XPath查找您想要的东西。
lxml
# install lxml
pip3 install lxml
然后这就是完成窍门的代码!
# xml snippet
xml = """\
<?xml version = "1.0" encoding="UTF-8" standalone="yes" ?>
<corpus>
<ver id="18" etude="EC1_Elec" elec="oui" niveau="1" critere="1.3" type="discours">
<part code="EC1_Elec_IW04_0">Ça existe sur des gros parcs Hlm mais c'est macro.</part>
</ver>
<ver id="30" etude="EC1_Elec" elec="oui" niveau="2" critere="" origine="IW" type="discours" fmc="motives">
<part code="EC1_Elec_IW01_0">Avant 75 on n'a pas isolé puis après, au fur et à mesure des règlementations.</part>
</ver>
<ver id="54" etude="EC1_Elec" elec="oui" niveau="1" critere="" origine="IW" type="discours" fmc="condition">
<part code="EC1_Elec_IW10_0">Le deuxième boitier, il est où ? s'il y en a un qui est à l'intérieur et qui remplace un bout de l'isolation, il est caché OK.</part>
</ver>
<ver id="897" etude="EC3_Elec" elec="oui" niveau="4" critere="4.1" origine="TR" type="discours" fmc="obstacle">
<part code="EC3_Elec_TR2_1">Avec l'économie d'énergie, on va imposer de plus en plus d'automatismes,</part>
<iwer>Çava influencer la demande pour ce type de solution c'est ça ?</iwer>
<part code="EC3_Elec_TR2_1">Je pense oui</part>
</ver>
</corpus>
"""
输出:
# use lxml...
from lxml import etree
# parse the xml snippet into an object tree
tree = etree.fromstring(bytes(xml, encoding='utf-8'))
# find all elements that have "fmc" attribute
for e in tree.findall(".//*[@fmc]"):
label = e.xpath("./@fmc")[0]
for c in e.getchildren():
# print value of "fmc" attribute and text of child element
print(f"{label:15}{c.text}")