4

我搜索了许多问答,但找不到足够具体的解决方案来提供帮助。

我有一个大的 xml 文件,需要根据另一个字段中的值在一个字段中进行有条件的“删除”。

例如:

<vehicle>...<manufacturer>JCB</manufacturer>....<item_category>JCB Tractors</item_category>...</vehicle><vehicle>...<manufacturer>Caterpillar</manufacturer>....<item_category>Digger</item_category>...</vehicle><vehicle>...<manufacturer>Caterpillar</manufacturer>....<item_category>Caterpillar Digger</item_category>...</vehicle>

需要成为

<vehicle>...<manufacturer>JCB</manufacturer>...<item_category>Tractors</item_category>...</vehicle><vehicle>...<manufacturer>Caterpillar</manufacturer>...<item_category>Digger</item_category>...</vehicle><vehicle>...<manufacturer>Caterpillar</manufacturer>....<item_category>Digger</item_category>...</vehicle>

理想情况下,我可以使用设置为 POSIX 扩展正则表达式的 textpad 中的查找和替换功能来应用该解决方案。

非常感谢对此的帮助,因为我已经用头撞了一段时间了!

如果我使用解析器,我可以隔离我想要“删除”的变量字符串

(?<=<manufacturer>)(.*?)(?=<\/manufacturer>)

是否可以使用该模式来隔离我实际要删除的字符串

例如,

(?<=<item_category>)(?<=<manufacturer>)(.*?)(?=<\/manufacturer>)(\s)
4

1 回答 1

2

您使用解析器的建议是正确的。

在正则表达式中处理标签可能是一场噩梦。某些程序在大型文本文件中的正则表达式模式失败并开始损坏位。确保首先备份您的工作。

但我同时看到了一个从中获得乐趣的机会。这仅是可能的,因为制造商名称与 item_category 的第一部分相同。

演示:https ://regex101.com/r/rO7pM0/1

解释

(\<manufacturer>([^<]*)<\/manufacturer>)(\s*)(\<item_category>)(?:\2\s*)?([^<]*)(<\/item_category>)

解释:

 (                            # Opens CG1
     \<manufacturer>          # Literal 
     (                        # Opens CG2
         [^<]*                # Negated Character class (excludes the characters within)
                                # None of: <
                                # * repeats zero or more times
     )                        # Closes CG2
     <                        # Literal <
     \/                       # Literal /
     manufacturer             # Literal manufacturer
     >                        # Literal >
 )                            # Closes CG1
 (                            # Opens CG3
     \s*                      # Token: \s (white space)
                                # * repeats zero or more times
 )                            # Closes CG3
 (                            # Opens CG4
     \<item_category>         # Literal 
 )                            # Closes CG4
 (?:                          # Opens NCG
     \2                       # A backreference to CG2
     \s*                      # Token: \s (white space)
                                # * repeats zero or more times
 )?                           # Closes NCG
                                # ? repeats zero or one times
 (                            # Opens CG5
     [^<]*                    # Negated Character class (excludes the characters within)
                                # None of: <
                                # * repeats zero or more times
 )                            # Closes CG5
 (                            # Opens CG6
     <                        # Literal <
     \/                       # Literal /
     item_category            # Literal item_category
     >                        # Literal >
 )                            # Closes CG6

更改(\s*),在演示中相当于两个标签之间的空间,([\s\S]*?)应该处理您的问题未提供的所有标签,但这要求每个车辆标签都有制造商和 item_category 标签。如果不是这样,您最终会得到损坏的数据,这就是解析器是更好解决方案的原因之一。

于 2015-04-25T05:50:57.613 回答