Ruby 如何找到一个不在里面的词<;a>;标签?

Ruby 如何找到一个不在里面的词<;a>;标签?,ruby,regex,Ruby,Regex,我需要正则表达式方面的帮助。我的任务与twitter的hashtags非常相似:我有一个以#开头的字符串。例如: foo #bar hello 在将哈希标记保存到数据库之前,我将其替换为链接,并获得如下字符串: foo <a href="bar">#bar</a> foo 之后,有时我需要重新解析字符串,我不想在标记中替换两次#bar。我需要一个regexp,它应该找到一个以开头的单词,而不是放在、和中,以便从您的输入中获取: foo #bar hello 对于您

我需要正则表达式方面的帮助。我的任务与twitter的hashtags非常相似:我有一个以
#
开头的字符串。例如:

foo #bar hello
在将哈希标记保存到数据库之前,我将其替换为链接,并获得如下字符串:

foo <a href="bar">#bar</a>
foo

之后,有时我需要重新解析字符串,我不想在
标记中替换两次
#bar
。我需要一个regexp,它应该找到一个以
开头的单词,而不是放在
中,以便从您的输入中获取:

foo #bar hello
对于您的输出:

foo <a href="bar">#bar</a> hello
foo你好
幂等,因此您可以通过函数将输出传回,并且它不会改变,您可以使用以下方法:

str1 = "foo #bar hello"
str2 = 'foo <a href="bar">#bar</a> hello'
replace_func = -> str { str.sub(/#(\w+)(?=[^<]*?(?:<[^\/]|$))/, '<a href="\1">#\1</a>')}
replace_func[str1]
replace_func[str2]
# both return: "foo <a href=\"bar\">#bar</a> hello"
str1=“foo#bar hello”
str2='foo hello'

替换_func=->str{str.sub(/#(\w+)(=[^Nokogiri的主要优点是,如果文本节点没有链接节点作为祖先(链接不能嵌套),并且它至少包含一个
#
(在其他文本节点内搜索是无用的),则可以使用XPath查询进行检查:

或者更简单:

doc.search('//text()[not(ancestor::a) and contains(., "#")]').each do |txt|
    txt.content.split(/(#\w+)/).each_with_index do |v, k|
        if k%2 > 0
            v = '<a href="http://domain.com?usr=' + v[1..-1] + '">' + v + '</a>'
        end
        txt.before(v)
    end
    txt.remove
end
doc.search('//text()[not(祖先::a)和contains(,“#”))。每个do都是txt|
txt.content.split(/(#\w+/)。每个_都有_索引do | v,k|
如果k%2>0
v=“”
结束
txt.before(v)
结束
删除
结束
注意:如果您只需要处理完整html文档的一部分,则必须进行少量更改以使其正常工作(您需要将html包装在根节点中,以使XPath查询正常工作):

doc=Nokogiri::HTML::fragment(“”+HTML\u doc+“”)
doc.search('.//text()[not(祖先::a)和contains(,“#”))。每个do都是txt|
txt.content.split(/(#\w+/)。每个_都有_索引do | v,k|
如果k%2>0
v=“”
结束
txt.before(v)
结束
删除
结束
doc.xpath('*/node()')。每个do |节点|
将node.html放置到\u html
结束
使用以下方法:

str1 = "foo #bar hello"
str2 = 'foo <a href="bar">#bar</a> hello'
replace_func = -> str { str.sub(/#(\w+)(?=[^<]*?(?:<[^\/]|$))/, '<a href="\1">#\1</a>')}
replace_func[str1]
replace_func[str2]
# both return: "foo <a href=\"bar\">#bar</a> hello"
/\<[^>]+\>[^<]*(\#[a-zA-Z]+)/

/\]+\>[^[^这是
foo
您期望的输出吗?
#bar
是否只有一层深?因为我想我有一个解决方案,只要这些不嵌套在任何其他标记中。当然,还有一个经典问题,您是否考虑过xml解析器?要操作HTML,您应该看看Nokogiri gem:必须重新分析这个字符串让我觉得你没有很好地理解你的逻辑。在修改它之前,先弄清楚对字符串的所有更改,这样你就只做一次,否则你会把自己弄得一团糟。
doc = Nokogiri::HTML::fragment('<div>' + html_doc + '</div>')
doc.search('.//text()[not(ancestor::a) and contains(., "#")]').each do |txt|

    txt.content.split(/(#\w+)/).each_with_index do |v, k|
        if k%2 > 0
            v = "<a href=\"http://mydomain.com?usr=#{v[1..-1]}\">#{v}</a>"
        end
        txt.before(v)
    end
    txt.remove
end
doc.xpath('*/node()').each do |node|
    puts node.to_html
end
/\<[^>]+\>[^<]*(\#[a-zA-Z]+)/
/\<[^>]+\>[^<]*(\#[a-zA-Z0-9]+)/