使用正则表达式提取字符串中的某些数据项

时间:2009-11-19 17:47:00

标签: regex string

<![Apple]!>some garbage text may be here<![Banana]!>some garbage text may be here<![Orange]!><![Pear]!><![Pineapple]!>

在上面的字符串中,我希望有一个匹配所有<![FruitName]!>的正则表达式,在这些<![FruitName]!>之间,可能有一些垃圾文本,我的第一次尝试是这样的:

<!\[[^\]!>]+\]!>

它有效,但正如你所看到的,我已经使用了这部分:

[^\]!>]+

这会杀死一些无辜的人。如果水果名称包含以下任何一个字符:] ! >它会被丢弃,我们喜欢吃水果,以至于不应该这样做。

我们如何构造一个在FruitName中完全不允许这个字符串]!>的正则表达式,而所有这些仍然可以获得?

上面的例子只是由我编写的,我只是想知道如果必须在正则表达式中完成正则表达式会是什么样的。

3 个答案:

答案 0 :(得分:6)

最简单的方法是<!\[.+?]!> - 根本不关心两个分隔符之间匹配的内容。只确保它始终与最终分隔符匹配 - 因此?使量词变得懒惰。

(另外,无需转义]

关于水果名称中应该“禁止”序列]!>的规范 - 这是隐含的,因为 是结束分隔符。

答案 1 :(得分:1)

要匹配水果名称,您可以使用:

<!\[(.*?)]!>

在打开<![后,这与]!>后面的文本数量最少相匹配。使用.*?代替.*,匹配的文本数量最少。

这是一个完整的正则表达式,用以下文字匹配每个水果:

<!\[(.*?)]!>(.*?)(?=(<!\[)|$)

这使用正向前瞻(?=xxx)来匹配下一个标记或字符串结尾的开头。积极的前瞻匹配,但不消耗,所以下一个水果可以匹配相同正则表达式的另一个应用程序。

答案 2 :(得分:1)

取决于您使用的语言,您可以通过简单的拆分(以及更易理解的简单正则表达式)使用您的语言提供的字符串方法。使用“!&gt;”拆分字符串作为分隔符。浏览每个字段,检查<!。如果找到,请将前面的所有字符替换为<!。这将给你所有的成果。我使用gawk来演示,但算法可以用你的语言实现

例如gawk

# set field separator as !>
awk -F'!>' '
{ 
  # for each field 
  for(i=1;i<=NF;i++){
    # check if there is <!
    if($i ~ /<!/){
        # if <! is found,  substitute from front till <!
        gsub(/.*<!/,"",$i)

    }
    # print result
    print $i
  }
}
' file

输出

# ./run.sh
[Apple]
[Banana]
[Orange]
[Pear]
[Pineapple]

不需要复杂的正则表达式。