1

我该如何解决以下问题?

我有一个像下面这样的 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 也会替换已经替换的内容。

4

4 回答 4

3

目前尚不清楚是否存在单个实例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>"

这将替换所有出现:

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"一个变量并通过将该目标插入到模式中来找到它:

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(word-break) 标记,这使得定义单词或子字符串匹配变得容易。您也可以"aaa"用多个单词替换。

于 2013-04-12T02:00:27.100 回答
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
于 2013-04-11T23:48:18.160 回答
1

我会使用正则表达式,Rubular是学习和测试表达式的好地方。有关如何使用 gsub 的更多信息,请查看Jayfields 博客文章。这可能不适合此问题的所有用例,因此您可能需要对其进行修改。

    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.
于 2013-04-11T23:36:10.413 回答
-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>" 
于 2013-04-11T23:57:09.060 回答