Ruby 正则表达式是否仅匹配直接子标记?

Ruby 正则表达式是否仅匹配直接子标记?,ruby,regex,rss,pcre,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..</de

我正在编写一个简单的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>

日落大道
http://www.imdb.com/title/tt0043014/
一个粗野的编剧写剧本。。
英语
8.6
我有一个方法,通过给定的标记和子标记,在一个简单的散列中提取它们。这是我的“方法”:

def从标签(文本,标签)中提取文本
text=~/(?*?)/m$~[:tag_text]:“”
结束
要解析频道,我首先提取其文本,然后使用预定义的标记数组(标题、链接等)提取它们的数据。但是,我希望正则表达式只匹配标记的直接子级


例如,在这里,如果我传递“title”、“link”、“description”、“language”和“rating”标记,我希望匹配除“rating”之外的所有标记(因为它是item的子项)。

我从评论中看到,您必须使用正则表达式而不是适当的XML解析器解析此RSS提要

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

doc=Nokogiri::XML(rss\u XML\u字符串)
doc.xpath('/channel/*')。每个do |节点|#用于根“channel”的每个子级。
下一步如果node.childrence.length>1#跳过具有多个子节点的节点。
放置node.name+':'+node.text
结束
#标题:日落大道
#链接:http://www.imdb.com/title/tt0043014/
#描述:一位黑客编剧写了一部剧本。。
#语言:英语

有一点需要注意,事情可能会变得比使用正则表达式更复杂,下面是一些建议:

您可以使用
[^]*?
而不是
*?
,前提是在XML中正确转义了“”

这将阻止在项中包含子项时提取该项的内容,该子项可能是或很多不是所需的行为(我认为在您的示例中这是正常的,但通常可能不正常)

如果您仍然需要提取“item”(如果有)的内容(除了可能的子项),那么您需要使用条件语句,如果我没有弄错的话,Ruby不支持这些语句


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

这就是为什么用正则表达式解析XML很棘手的原因。可能(对于定义良好的情况),但需要技巧。是否需要使用正则表达式es?使用xpath或通过dom解析解决这个问题似乎更容易…MichaelMyers-我知道这很棘手,但格式定义良好。春分-是的,这是一个要求。顺便问一下,这是红宝石吗?我强烈建议阅读“”。它涵盖了试图使用正则表达式解析HTML或XML的问题。虽然编写RSS解析器可能是“有趣的”,但你确实应该考虑重新使用一个轮子,而不是发明自己的。野生的RSS很混乱,有几个规范,不包括ATOM,ATOM也用于提要。我写了一篇分析所有变体的文章,处理了数百个提要,这是一个“有趣”的挑战。
def extract_text_from_tag(text, tag)
  text =~ /<#{tag}.*?>(?<tag_text>.*?)<\/#{tag}>/m ? $~[:tag_text] : ''
end