正则表达式只匹配直接子标签?

时间:2013-02-14 15:04:48

标签: ruby regex rss pcre

我正在编写一个简单的RSS解析器(我知道已有很多已编写),我偶然发现了一个问题。假设我有以下RSS提要:

<channel>
  <title>Sunset Boulevard</title>
  <link>http://www.imdb.com/title/tt0043014/</link>
  <description>A hack screenwriter writes a screenplay..</description>
  <language>English</language>
  <item>
    <rating>8.6</rating>
  </item>
</channel>

我有一个方法,通过给定的标签和子标签在简单的哈希中提取它们。这是我的“方法”:

def extract_text_from_tag(text, tag)
  text =~ /<#{tag}.*?>(?<tag_text>.*?)<\/#{tag}>/m ? $~[:tag_text] : ''
end

要解析频道,我首先提取其文本,然后使用预定义标签(标题,链接等)数组,提取其数据。但是,我希望我的正则表达式只匹配我的标记的直接子项。

例如,如果我传递'标题','链接','描述','语言'和'评分'标签,我想匹配所有这些标签,除了'评级'(因为它是项目的孩子) )。

2 个答案:

答案 0 :(得分:1)

我从评论中看到,您必须使用正则表达式而不是正确的XML解析器来解析此RSS源。

然而,作为一个反例,这是使用Nokogiri的解决方案:

doc = Nokogiri::XML(rss_xml_string)
doc.xpath('/channel/*').each do |node| # For each child of the root "channel".
  next if node.children.length > 1 # Skip nodes with multiple children.
  puts node.name + ': ' + node.text
end
# title: Sunset Boulevard
# link: http://www.imdb.com/title/tt0043014/
# description: A hack screenwriter writes a screenplay..
# language: English

答案 1 :(得分:0)

有一点需要注意的是,除了正则表达式之外,事情可能会变得复杂,这里有一些建议:

而不是.*?您可以使用[^<>]*?,假设“&lt;”和“&gt;”在XML中正确转义。

如果 item 你的例子,但一般来说可能不行。)

如果您仍然需要提取除“可能的子项”之外的“item”(如果有)的内容,则需要使用条件语句,如果我没有记错,则不支持Ruby。

您可以使用一种方法替换它,以测试标记是否包含子元素并相应地应用正则表达式,但它确实变得相当复杂。