正则表达式将匹配此(XML-ish)输入模式

时间:2014-11-07 07:43:39

标签: regex

我需要解析一个看起来像这样的XML片段:

<tag name="books">books1</tag> 
<tag name="textBooks"> textBooks1</tag> 
<tag name="textBooks"> textBooks2</tag> 
<tag name="textBooks"> textBooks3</tag> 
<tag name="textBooks"> textBooks4</tag> 
<tag name="textBooks"> textBooks5</tag> 
<tag name="books">books2</tag> 
<tag name="textBooks"> textBooks1</tag> 
<tag name="textBooks"> textBooks2</tag> 
<tag name="books">books3</tag>
<tag name="textBooks"> textBooks4</tag> 
<tag name="textBooks"> textBooks5</tag> 

我需要将所有标记name="textBooks"包括<tag name="books"></tag>直到最后一个textBooks <tag name="books"></tag>之前。

所以结果如下

<tag name="books">books1</tag> 
<tag name="textBooks"> textBooks1</tag> 
<tag name="textBooks"> textBooks2</tag> 
<tag name="textBooks"> textBooks3</tag> 
<tag name="textBooks"> textBooks4</tag> 
<tag name="textBooks"> textBooks5</tag> 

<tag name="books">books2</tag> 
<tag name="textBooks"> textBooks1</tag> 
<tag name="textBooks"> textBooks2</tag> 

<tag name="books">books3</tag>
<tag name="textBooks"> textBooks4</tag> 
<tag name="textBooks"> textBooks5</tag> 

1 个答案:

答案 0 :(得分:0)

如果您的问题实际上只是“哪个正则表达式与<tag name="books">匹配”,则答案只是<tag name="books">

您的输出示例看起来像是要在每次出现之前插入一个空行,除了第一个,所以可能尝试类似

sed '1b;/<tag name="books">/i\
' xml-fragment.txt

如果您的意思是,请抓取每组name="textBooks"标记以及前面的name="books"标记及其各自的内容,尝试类似

的内容
(<tag name="books">[^<>]*(?:</tag>\s*<tag name="textBooks">[^<>]*)*</tag>)

其中\s匹配包含Perl扩展的正则表达式实现中的空格(包括换行符)(所以,不是sed,而是大多数现代编程语言,包括PHP [我在这里包含了一些诙谐的评论]关于它适用于......大多数事情]和Python)。

请注意,默认情况下,许多正则表达式实现都是面向行的 - 将上面的多行正则表达式应用于单行输入肯定不起作用。但假设您正在做类似

的事情
lines = file.read()
re.match(regex, lines)
:

你应该发现它能做你想做的事。

如评论中所示,您确实应该使用XML工具进行XML输入。如果您的输入不是正确的XML,也许您可​​以对其进行预处理,并对其进行后处理以删除预处理器必须添加的任何内容,以使其可以被XML处理管道接受。