我在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或类似的工具来做。

    <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>

我想从这些标签中删除坏字符(客户端manuf和essid)。
来自:<client-manuf>SHENZHEN BILIAN ELECTRONIC CO.&#x ef;&#x bc;&#x 8c;LTD</client-manuf>
到(或这个):<client-manuf>SHENZHEN BILIAN ELECTRONIC CO. LTD</client-manuf>
到(或这个):<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>
到(或这个):<essid cloaked="true"></essid>
到(或这个):<essid cloaked="true">N/A SSID</essid>
到(或这个):<essid cloaked="false">WiFi MTN</essid>
for example, two bad chars:

1: 0;

2: &#x

这是我的解决办法。但它不能很好地满足我的需要:
sed -e '/<essid cloaked="\(true\|false"\)>*.*<\/essid>/ s/\(&#x\|0;\)//g' a.txt

最佳答案

你的sed命令看起来没那么糟糕,只是留下了很多空白。
由于sed通常是贪婪的,所以可以用“*”指定任意数量的空间。

cat bad.xml | sed '/<essid cloaked="\(true\|false"\)>*.*<\/essid>/ s/ *\(&#x\|0;\) *//g'

另一方面,如果有一些有效文本,则可能不希望将其粘在一起,因此可以为每个删除的模式添加一个空格:
cat bad.xml | sed '/<essid cloaked="\(true\|false"\)>*.*<\/essid>/ s/ *\(&#x\|0;\) */ /g'

最后,您可以将多个空间压缩为一个:
cat bad.xml | sed '/<essid cloaked="\(true\|false"\)>*.*<\/essid>/{s/ *\(&#x\|0;\) */ /g;s/  */ /g}'

注意,构造{foo;bar}将这两个命令绑定到一个命令块,只在before-grapped模式上操作。第二种模式会影响整个文件。
再加上一对蒙面括号和一个蒙面加号:
cat bad.xml | sed '/<essid cloaked="\(true\|false"\)>*.*<\/essid>/{s/\( *\(&#x\|0;\) *\)\+/ missing essid /g;s/  */ /g}'

你可以用一件事来代替一个重复出现的模式。
      s/\( *\(&#x\|0;\) *\)\+/ missing essid /;
      ^  (   (pattern1)   )+ / replacement   /(g now obsolete
         (pattern .......2)

内部模式是可选的&x或0;。
外部模式是内部模式,可以选择由类似
     "0;"
     "0; "
     " 0; "
     " 0;"
     "    0;  "
     "    &#x"

等等。
您希望内部模式(我们称之为x)重复一次或多次,因此是+模式。但是没有parens,+只处理最后一个字符,而不是整个模式。
你必须学会这种正则表达式语言。找一个教程。你不能要求生活中的每一个变化。
有一个良好的,基本的理解会很快得到回报。你不需要什么都知道壁炉,但基本的东西,应该有一个良好的估计,什么是可能的,什么不是。然后是回购,用来搜索那些很少使用的东西。然后你可能只会问那些复杂的问题。

08-07 13:26