使用正则表达式查找并添加缺少的子字符串(Python)

时间:2018-10-31 09:08:55

标签: python regex python-3.x

我有一个字符串格式的XML,看起来或多或少像这样:

<item>  
    <property 1> value </property 1>
    <property 2> value </property 2>
    <property 3> value </property 3>
</item>

<item>  
    <property 1> value </property 1>
    <property 2> value </property 2>
    <property 3> value </property 3>
    <property 4> value </property 4>
</item>

如本例所示,第一个item缺少property 4。我想做的是找到所有缺少此item的{​​{1}}并手动添加。

这是一个更大的Python脚本的一部分,我尝试使用regex方法re.findall和re.search查找所有丢失的子字符串,然后使用re.sub添加所述子字符串,但是我做不到完全可以工作。

任何帮助将不胜感激:) 谢谢

3 个答案:

答案 0 :(得分:0)

甚至不必理会正则表达式解决方案。由于XML是一种非正规语言,因此正则表达式解决方案注定会失败(如果不是今天,那么明天就是明天,只要XML字符串发生变化)。

使用适当的XML工具并搜索所需的标签。如果丢失,请添加它。 您只需要确保输入字符串采用有效的XML格式即可(这意味着根元素且标记名称中没有空格)。

from xml.etree import ElementTree as ET

xml_str = '''<root>
                <item>
                    <property_1> value </property_1>
                    <property_2> value </property_2>
                    <property_3> value </property_3>
                </item>
                <item>
                    <property_1> value </property_1>
                    <property_2> value </property_2>
                    <property_3> value </property_3>
                    <property_4> value </property_4>
                </item>
             </root>'''

xml = ET.fromstring(xml_str)
for item in xml.iter('item'):
    prop_4 = item.find('property_4')
    if prop_4 is None:
        prop_4 = ET.Element('property_4')
        prop_4.text = ' value '
        item.append(prop_4)
print(ET.tostring(xml).decode())

#  <root>
#      <item>
#          <property_1> value </property_1>
#          <property_2> value </property_2>
#          <property_3> value </property_3>
#          <property_4> value </property_4>
#      </item>
#      <item>
#          <property_1> value </property_1>
#          <property_2> value </property_2>
#          <property_3> value </property_3>
#          <property_4> value </property_4>
#      </item>
#  </root>

答案 1 :(得分:0)

可以不用正则表达式来完成。使用Python XML libray。

先从字符串加载xml,然后查看每个子元素是否具有“ property4”:

public static void main(String[] args) {
    Set<Object> bars = new HashSet<Object>();
    Bar bar1 = new Bar(1, 2);
    Bar bar2 = new Bar(1, 3);

    bars.add(bar1);
    bars.add(bar2); // no effect since bar1.equals(bar2)
    // only bar1 in the set

    bars.remove(bar2); // removes bar1 since bar1.equals(bar2)
    bars.add(bar2);
    // only bar2 in the set
}

static class Bar {
    int field1;
    int field2;

    public Bar(int field1, int field2) {
        this.field1 = field1;
        this.field2 = field2;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Bar)) return false;
        Bar bar = (Bar) o;
        return field1 == bar.field1;
    }

    @Override
    public int hashCode() {
        return Objects.hash(field1);
    }
}

请注意,为了从字符串中加载xml,您需要有效且格式正确的xml。

答案 2 :(得分:0)

  

我想做的就是找到每个缺少“属性4”的“项目”,然后手动添加。
  我尝试过使用正则表达式方法re.findall和re.search来查找所有丢失的子字符串,然后使用re.sub来添加所述子字符串,但是我根本无法使它工作。

适合您的字符串格式的正则表达式为<item(?:(?!<property 4).)*?(?=</item>)-它从开始到结束标签(不包括其结束标签)都与item匹配,但前提是{{1} }出现。可以将其合并到单个re.sub调用中:

property 4