我需要幫助正則表達式。我的任務與Twitter的主題標籤非常相似:我有一個字符串,文字盯着#
。例如:如何找到不在<a>標籤內的單詞?
foo #bar hello
我與鏈接替換井號標籤之前保存到數據庫並獲取字符串是這樣的:
foo <a href="bar">#bar</a>
後,有時我需要重新解析字符串,我不想要在<a>
標籤內替換#bar
兩次。我需要regexp應該找到一個字開始#
和放置在>
,<
,>
和</a>
內。
我需要幫助正則表達式。我的任務與Twitter的主題標籤非常相似:我有一個字符串,文字盯着#
。例如:如何找到不在<a>標籤內的單詞?
foo #bar hello
我與鏈接替換井號標籤之前保存到數據庫並獲取字符串是這樣的:
foo <a href="bar">#bar</a>
後,有時我需要重新解析字符串,我不想要在<a>
標籤內替換#bar
兩次。我需要regexp應該找到一個字開始#
和放置在>
,<
,>
和</a>
內。
從您的輸入獲得:
foo #bar hello
到您的輸出:
foo <a href="bar">#bar</a> hello
idempotently,這樣你就可以通過你的函數傳遞你的輸出回來了,它不會改變,你可以使用這個:
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"
另外引入nokogiri可以非常簡單地使用:
require 'nokogiri'
doc = Nokogiri::XML('<p>' + you_string + '</p>')
doc.search('//p').each do |node|
node.content = node.content.sub(/#\w+/)
end
與引入nokogiri的主要優點是,你可以很容易地使用XPath查詢檢查,如果一個文本節點沒有鏈接節點的祖先(可鏈接「T被嵌套),如果它含有至少一個#
(也沒用到其它文本節點內搜索):
require 'nokogiri'
doc = Nokogiri::HTML(html_doc)
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
node = Nokogiri::XML::Node.new("a", doc)
node.content = v
node['href'] = "http://domain.com?usr=" + v[1..-1]
else
node = v
end
txt.before(node)
end
txt.remove
end
puts doc.to_html
或多個簡單:
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
注意:如果你需要處理一個完整的HTML文檔的唯一部分,你必須做出一點改變,使其作品(你需要用的HTML中根節點,使XPath查詢工作):
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-Z]是字母,可能是在這個詞#後。
/\<[^>]+\>[^<]*(\#[a-zA-Z0-9]+)/
是這個'富#bar'你期望的輸出:如果你想數也包括可以用這個? –
'#bar'只會是一個深度嗎?因爲我認爲我有一個解決方案,只要這些解決方案不嵌套在任何其他標記中。 –
當然還有一個經典的問題,你是否考慮過一個XML解析器? –