2013-04-11 93 views
0

如何解决以下问题?Ruby只用另一个字符串替换完全匹配的字符串

我有一个HTML字符串类似以下之一:

<p>aaa, b aa aaaaa?<br/>Next possible text b bb aa b.</p> 

现在,我想只有

"aaa" 

"<div class='special'>aaa</div>" 

新的字符串替换之后替换,例如:

<p><div class='special'>aaa</div>, b aa aaaaa?<br/>Next possible text b bb aa b.</p> 

所以我想要一个通用替代品,它只替换完全匹配的字符串。 “aaa”只是一个例子。它也可能是“bb”或“两个单词”(=>两个单词,所以text.split在我看来不起作用)。

任何人有这样一个动态的发现,匹配和替代者的想法?

我想它已经像以下:

items = ["aaa", "a", "aa", "aa b", "c"] 
text = "<p>aaa, b aa aaaaa?<br/>Next possible text b bb aa b.</p>" 
words = text.split => ["<p>aaa,", "b", "aa", "aaaaa?<br/>Next", "possible", "text", "b", "bb", "aa", "b.</p>"] 
new_words = [] 

words.each do |w| 
    items.each do |item| 
    if w == item 
     w = '<div class="special">#{item}</div>' 
    end 
    end 
    new_words << w 
end 
text = new_words.join(" ") 

结果:

"<p>aaa, b <div class='special'>aa</div> aaaaa?<br/>Next possible text b bb <div class='special'>aa</div> b.</p>" 

但它应该是:

"<p><div class='special'>aaa</div>, b <div class='special'>aa</div> aaaaa?<br/>Next possible text b bb <div class='special'>aa b</div>.</p>" 

我最大的问题是:

  • 特殊字符,例如“,。?()%€” - 字符串末尾的字符 =>“aaa”,来自示例
  • 具有相同部分的子字符串=>像“aaa”和“aa”
  • 两个字作为一个项目=>像“AA(b)”,从示例

有人用于固定我的问题的想法?

编辑:东西是只为我更换一个占位符..我真正的更换也可以:

%Q(<dfn title="#{strip_tags item.text}">#{item.name}</dfn>) 

item.text是一切=>可能还包含“AAA” item.name是例如“aaa”

所以多个gsub会替换已经替换的内容。

回答

1

我会用一个正则表达式,Rubular是学习和测试你的表达式的好地方。有关如何使用gsub检出Jayfields Blog post的更多信息。这可能不适合您的所有用例,因此您可能需要对其进行修改。

str.gsub /^<p>a{3}/, "<div class='special'>aaa</div>" 


    What this says is starting at the beginning of the string (^) 
    find <p> and 3 assurances of the letter a. 
+0

它应该是'sub'而不是'gsub',因为OP只需要第一个匹配,并没有指定它总是在标签旁边。 – iain

2

您正在寻找String#sub(不gsub

s = "<p>aaa, b aa aaaaa?<br/>Next possible text b bb aa b.</p>" 
# => "<p>aaa, b aa aaaaa?<br/>Next possible text b bb aa b.</p>" 
match = "aaa" 
# => "aaa" 
replacement = "<div class='special'>aaa</div>" 
# => "<div class='special'>aaa</div>" 
s.sub match, replacement 
# => "<p><div class='special'>aaa</div>, b aa aaaaa?<br/>Next possible text b bb aa b.</p>" 
"<p><div class='special'>aaa</div>, b aa aaaaa?<br/>Next possible text b bb aa b.</p>" == _ 
# => true 
+0

但如果字符串是“

aaa,b aa aaaaa?
下一个可能的文本b bb aa b.aaa。

”,那将不起作用? – Mattherick

+0

*如果你保存*'match' *变量的内容是相同的,*它不起作用*如果你有不同的字符串,那么你可以通过'match =“b bb”'(或者你希望匹配的字符串中的任何内容),或者可能更好,编辑你的问题,并让我们知道字符串是如何变化的,以及你如何知道哪个部分要抓取。 – iain

-1

这里是你想要的(当然使用GSUB)的替代品的方法:

def replacer(orig,pattern,replace) 
    orig.gsub(/#{pattern}(\s|\.|,)/,replace+'\1').to_s 
end 

2.0.0dev :001 > def replacer(orig,pattern,replace) 
2.0.0dev :002?>  orig.gsub(/#{pattern}(\s|\.|,)/,replace+'\1').to_s 
2.0.0dev :003?> end 
=> nil 
2.0.0dev :004 > replacer("<p>aaa, b aa aaaaa?<br/>Next possible text b bb aa b.</p>", "aaa", "<div class='special'>aaa</div>") 
=> "<p><div class='special'>aaa</div>, b aa aaaaa?<br/>Next possible text b bb aa b.</p>" 
2

目前尚不清楚是否有一个aaa或多个的实例,并且您是希望它们全部被替换,还是只是第一个。

这将只更换第一:通过插值该目标进入模式

text = "<p>aaa, b aa aaaaa?<br/>Next possible text b bb aa b.</p>" * 2 
=> "<p>aaa, b aa aaaaa?<br/>Next possible text b bb aa b.</p><p>aaa, b aa aaaaa?<br/>Next possible text b bb aa b.</p>" 

text.gsub(/\b(aaa)\b/, %q"<div class='special'>\1</div>") 
=> "<p><div class='special'>aaa</div>, b aa aaaaa?<br/>Next possible text b bb aa b.</p><p><div class='special'>aaa</div>, b aa aaaaa?<br/>Next possible text b bb aa b.</p>" 

你可以把"aaa"成一个变量,并找到它:

text = "<p>aaa, b aa aaaaa?<br/>Next possible text b bb aa b.</p>" 
text.sub(/\b(aaa)\b/, %q"<div class='special'>\1</div>") 
=> "<p><div class='special'>aaa</div>, b aa aaaaa?<br/>Next possible text b bb aa b.</p>" 

这将替换所有出现

target = 'aaa' 
text.gsub(/\b(#{ target })\b/, %q"<div class='special'>\1</div>") 
=> "<p><div class='special'>aaa</div>, b aa aaaaa?<br/>Next possible text b bb aa b.</p><p><div class='special'>aaa</div>, b aa aaaaa?<br/>Next possible text b bb aa b.</p>" 

正则表达式有\b(单词分隔)标记,可以很容易地定义单词或子串匹配。您也可以用多个单词替换"aaa"

相关问题