首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何删除或替换两个xml标记之间的特定字符[linux、python、lxml、sed、awk、.]?

如何删除或替换两个xml标记之间的特定字符[linux、python、lxml、sed、awk、.]?
EN

Stack Overflow用户
提问于 2018-02-16 12:09:31
回答 2查看 500关注 0票数 3

我在python中使用LXML库进行XML解析。

在XML文件中,我有一些错误字符,导致python中的错误:

lxml.etree.XMLSyntaxError: CharRef

在打开和获取python中的XML文件内容之前,我必须从两个标记中删除坏字符:

1:<essid cloaked="true">....</essid><essid cloaked="false">....</essid>

2:<client-manuf>....</client-manuf>

XML文件的大小很大。所以我想用sed或者awk或者类似的工具来做。

代码语言:javascript
复制
    <crypt>0</crypt>
        <total>20    50</total>
        <fragments>0</fragments>
        <retries>0</retries>
    </packets>
    <datasize>0</datasize>
    <wireless-client number="1" type="established" first-time="Thu Feb 15 16:45:43 2018" last-time="Thu Feb 15 16:45:43 2018">
        <client-mac>08:EA:40:D0:55:43</client-mac>
        <client-manuf>SHENZHEN BILIAN ELECTRONIC CO.&#x  ef;&#x  bc;&#x  8c;LTD</client-manuf>
        <essid cloaked="true">&#x   0;&#x   0;&#x   0;&#x   0;&#x   0;</essid>
        <channel>8</channel>
        <maxseenrate>1.000000</maxseenrate>
        <carrier>IEEE 802.11b+</carrier>
        <encoding>CCK</encoding>
        <packets>
            <LLC>0</LLC>
            <data>0</data>
            <crypt>0</crypt>

我想从这些标记(client-manuf和essid)中删除坏字符。

来自:<client-manuf>SHENZHEN BILIAN ELECTRONIC CO.&#x ef;&#x bc;&#x 8c;LTD</client-manuf>

To (或此):<client-manuf>SHENZHEN BILIAN ELECTRONIC CO. LTD</client-manuf>

To (或此):<client-manuf>SHENZHEN BILIAN ELECTRONIC CO</client-manuf>

来自:<essid cloaked="true">&#x 0;&#x 0;&#x 0;&#x 0;&#x 0;</essid>

来自:<essid cloaked="false">&#x 0;&#x WiFi 0;&#x MTN 0;&#x 0;&#x 0;</essid>

To (或此):<essid cloaked="true"></essid>

To (或此):<essid cloaked="true">N/A SSID</essid>

To (或此):<essid cloaked="false">WiFi MTN</essid>

代码语言:javascript
复制
for example, two bad chars:

1: 0;

2: &#x

这是我的解决方案。但它对我的需求不起作用:

sed -e '/<essid cloaked="\(true\|false"\)>*.*<\/essid>/ s/\(&#x\|0;\)//g' a.txt

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-02-17 20:59:41

您的sed命令看起来并没有那么糟糕,它只是留下了许多空白。

因为sed通常是贪婪的,所以您可以使用“*”指定任意数量的空间。

代码语言:javascript
复制
cat bad.xml | sed '/<essid cloaked="\(true\|false"\)>*.*<\/essid>/ s/ *\(&#x\|0;\) *//g'

另一方面,如果有一些有效的文本,您可能不想将它粘在一起,因此可以在每个移除的模式中添加一个空格:

代码语言:javascript
复制
cat bad.xml | sed '/<essid cloaked="\(true\|false"\)>*.*<\/essid>/ s/ *\(&#x\|0;\) */ /g'

最后,您可能会将多个空格压缩为一个:

代码语言:javascript
复制
cat bad.xml | sed '/<essid cloaked="\(true\|false"\)>*.*<\/essid>/{s/ *\(&#x\|0;\) */ /g;s/  */ /g}'

请注意,构造{foo;bar}将这两个命令绑定到一个命令块,仅在“前抓取”模式上操作。第二种模式将影响整个文件。

加上另一对蒙面圆括号和一个蒙面加上:

代码语言:javascript
复制
cat bad.xml | sed '/<essid cloaked="\(true\|false"\)>*.*<\/essid>/{s/\( *\(&#x\|0;\) *\)\+/ missing essid /g;s/  */ /g}'

你可以用一件事来代替反复出现的模式。

代码语言:javascript
复制
      s/\( *\(&#x\|0;\) *\)\+/ missing essid /;
      ^  (   (pattern1)   )+ / replacement   /(g now obsolete
         (pattern .......2)

内部模式是一个可选的&#x或0;。外部模式是内部模式,可以选择地由空格(如

代码语言:javascript
复制
     "0;"
     "0; "
     " 0; "
     " 0;"
     "    0;  "
     "    &#x"

诸若此类。

您希望内部模式,让我们称之为X,被重复一次或多次,因此+。但是没有父母,+只处理最后一个字符,而不是整个模式。

你必须学会这种正则语言。找个教程。你不能要求你生活中需要的每一个可能的变化。

有了良好的基本理解,很快就会有回报。你不需要知道所有的一切,但基本的东西,应该有一个很好的估计,什么是可能的,什么不是。然后再做个回购,去寻找东西,很少用。然后你可能只会问那些困难/复杂的事情。

票数 1
EN

Stack Overflow用户

发布于 2018-02-16 14:51:52

使用etree.XMLParser对象的正确方法(仅限lxml.etree):

代码语言:javascript
复制
import re
from lxml import etree

tags_to_fix = ['clientssss-manuf', 'client-manuf', 'essid']
parser = etree.XMLParser(recover=True)   # recovery mode !
tree = etree.parse("input.xml", parser)

for el in tree.xpath('//*[name()="clientssss-manuf" or name()="client-manuf" or name()="essid"]'):
    el.text = re.sub(r'\w{1,2};\s*', '', el.text).strip()

tree.write("output.xml", encoding="utf-8", pretty_print=True)

产生的output.xml中的关键片段

代码语言:javascript
复制
...
<packets>
<crypt>0</crypt>
        <total>20    50</total>
        <fragments>0</fragments>
        <retries>0</retries>
    </packets>
    <datasize>0</datasize>
    <wireless-client number="1" type="established" first-time="Thu Feb 15 16:45:43 2018" last-time="Thu Feb 15 16:45:43 2018">
        <client-mac>08:EA:40:D0:55:43</client-mac>
        <clientssss-manuf>SHENZHEN BILIAN ELECTRONIC CO.  LTD</clientssss-manuf>
        <client-manuf>SHENZHEN BILIAN ELECTRONIC CO.  LTD</client-manuf>
        <essid cloaked="true"></essid>
        <channel>8</channel>
        <maxseenrate>1.000000</maxseenrate>
        <carrier>IEEE 802.11b+</carrier>
        <encoding>CCK</encoding>
        <packets>
            <LLC>0</LLC>
            <data>0</data>
            <crypt>0</crypt>
</packets></wireless-client>
...
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48826469

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档