如何使用Ruby替换字符串中出现的每个模式?

如何使用Ruby替换字符串中出现的每个模式?,ruby,string,replace,Ruby,String,Replace,我有一个XML文件太大了。为了使它更小,我想用同一事物的更短版本替换所有标记和属性名 因此,我实施了以下措施: string.gsub!(/<(\w+) /) do |match| case match when 'Image' then 'Img' when 'Text' then 'Txt' end end puts string string.gsub!(/试试这个: string.gsub!(/(<\/?)(\w+)/) do |matc

我有一个XML文件太大了。为了使它更小,我想用同一事物的更短版本替换所有标记和属性名

因此,我实施了以下措施:

string.gsub!(/<(\w+) /) do |match|
    case match
    when 'Image' then 'Img'
    when 'Text'  then 'Txt'
    end
end

puts string
string.gsub!(/试试这个:

string.gsub!(/(<\/?)(\w+)/) do |match|
  tag_mark = $1
  case $2
  when /^image$/i
    "#{tag_mark}Img"
  when /^text$/i
    "#{tag_mark}Txt"
  else
    match
  end
end  
string.gsub!(/(试试这个:

string.gsub!(/(<\/?)(\w+)/) do |match|
  tag_mark = $1
  case $2
  when /^image$/i
    "#{tag_mark}Img"
  when /^text$/i
    "#{tag_mark}Txt"
  else
    match
  end
end  
string.gsub!(/(还有另一种方法:

class String
  def minimize_tags!
    {"image" => "img", "text" => "txt"}.each do |from,to|
      gsub!(/<#{from}\b/i,"<#{to}")
      gsub!(/<\/#{from}>/i,"<\/#{to}>")
    end
    self
  end
end
类字符串
def最小化\u标签!
{“image”=>“img”,“text”=>“txt”}。每个都做|从,到|
gsub!(/还有另一种方法:

class String
  def minimize_tags!
    {"image" => "img", "text" => "txt"}.each do |from,to|
      gsub!(/<#{from}\b/i,"<#{to}")
      gsub!(/<\/#{from}>/i,"<\/#{to}>")
    end
    self
  end
end
类字符串
def最小化\u标签!
{“image”=>“img”,“text”=>“txt”}。每个都做|从,到|

gsub!(/以下是使用解析器的妙处,例如:

这使您可以操纵选定的标记(节点)及其属性:

require 'nokogiri'

xml = <<EOT
<xml>
  <Image ImagePath="path/to/image">image comment</Image>
  <Text TextFont="courier" TextSize="9">this is the text</Text>
</xml>
EOT

doc = Nokogiri::XML(xml)
doc.search('Image').each do |n| 
  n.name = 'img' 
  n.attributes['ImagePath'].name = 'path'
end
doc.search('Text').each do |n| 
  n.name = 'txt'
  n.attributes['TextFont'].name = 'font'
  n.attributes['TextSize'].name = 'size'
end
print doc.to_xml
# >> <?xml version="1.0"?>
# >> <xml>
# >>   <img path="path/to/image">image comment</img>
# >>   <txt font="courier" size="9">this is the text</txt>
# >> </xml>
需要“nokogiri”
xml=
# >> 
#>>图像评论
#>>这是文本
# >> 
如果您需要遍历每个节点,可能需要对标记名进行通用转换,则可以使用
doc.search('*')。each
。这将比搜索单个标记慢,但如果您需要更改每个标记,则可能会减少代码


使用解析器的好处是,即使XML的布局发生变化,它也能工作,因为它不关心空格,即使属性顺序发生变化,它也能工作,使代码更加健壮。

使用解析器的好处如下:

这使您可以操纵选定的标记(节点)及其属性:

require 'nokogiri'

xml = <<EOT
<xml>
  <Image ImagePath="path/to/image">image comment</Image>
  <Text TextFont="courier" TextSize="9">this is the text</Text>
</xml>
EOT

doc = Nokogiri::XML(xml)
doc.search('Image').each do |n| 
  n.name = 'img' 
  n.attributes['ImagePath'].name = 'path'
end
doc.search('Text').each do |n| 
  n.name = 'txt'
  n.attributes['TextFont'].name = 'font'
  n.attributes['TextSize'].name = 'size'
end
print doc.to_xml
# >> <?xml version="1.0"?>
# >> <xml>
# >>   <img path="path/to/image">image comment</img>
# >>   <txt font="courier" size="9">this is the text</txt>
# >> </xml>
需要“nokogiri”
xml=
# >> 
#>>图像评论
#>>这是文本
# >> 
如果您需要遍历每个节点,可能需要对标记名进行通用转换,则可以使用
doc.search('*')。each
。这将比搜索单个标记慢,但如果您需要更改每个标记,则可能会减少代码


使用解析器的好处是,即使XML的布局发生变化,解析器也能工作,因为它不关心空格,即使属性顺序发生变化,解析器也能工作,从而使代码更加健壮。

结束标记名后面没有空格,所以这种匹配开始标记和结束标记的尝试不会像写的那样工作……谢谢u@glenn,我意识到空格不是打字错误。我对我的代码进行了更新。不,你不能只删除空格,除非你知道不再有以这些开头的标记。例如,TEXTAREA或IMAGEMAP现在会被你的代码搞砸。好吧,@glenn,我做了一个更好的更新。谢谢你的检查。我感觉像个大三学生向老师提交作业:)我想象不出还有更多的场景遗漏了regexp。是的,看起来它会起作用。不过看起来有点难看:两行芬尼基代码和一个额外的regexp求值,用于您要更改的每个标记。也许最好从原始问题的前提(使用block参数到gsub)后退一步,并将解决方案转过来。我将添加一个类似这样的替代选项作为另一个答案…结束标记名后不会有空格,因此尝试匹配开始标记和结束标记不会像写的那样起作用…谢谢@glenn,我意识到空格不是打字错误。我对代码进行了更新。不,你不能只去掉空格,除非你知道不再有标记从这些开始。例如,TEXTAREA或IMAGEMAP现在会被你的代码搞砸。好的,@glenn,我做了一个更好的更新。谢谢你的检查。我感觉自己就像一个初中生向老师提交作业:)我想象不出还有更多的场景遗漏了regexp。是的,看起来它会起作用。不过看起来有点难看:两行芬尼基代码和一个额外的regexp求值,用于您要更改的每个标记。也许最好从原始问题的前提(使用block参数到gsub)后退一步,并将解决方案转过来。我将添加一个类似的选项作为另一个答案…我在这里做了什么?SnIDE,但是严肃的答案1:不使用XML处理器。SNIDE,但是严肃的回答2:.SNIDE,但是严肃的答案3:这些变化可能会有非常小的尺寸减小。考虑容器(GZIP)或者二进制XML压缩器,如果真的需要的话。愉快的编码。@pst:是的,先生。不过,我不仅需要用于XML的脚本,还需要用于其他(部分自定义)格式的脚本,这样XML处理器就不会剪切它。更正确的注释应该是“4:首先使用XML”.像JSON这样的东西可以在紧要关头解决我所有的问题——但当我提出这个建议时,我的老板拒绝了。这很悲哀,但却是真的。我怎么会忘记呢#4?:(BoHS限制中的快乐编码)我在这里做了什么?SnIDE,但是严肃的答案1:不使用XML处理器。SnIDE,但是严肃的回答2:SnIDE,但是严肃的答案3:这些变化可能会有非常小的尺寸减小。考虑容器(GZIP)或者二进制XML压缩器,如果真的需要的话。愉快的编码。@pst:是的,先生。不过,我不仅需要用于XML的脚本,还需要用于其他(部分自定义)格式的脚本,这样XML处理器就不会剪切它。更正确的注释应该是“4:首先使用XML”.像JSON这样的东西可以在紧要关头解决我所有的问题——但当我提出这个建议时,我的老板拒绝了。这很悲哀,但却是真的。我怎么会忘记呢#4?:(在boss-CONSTRIENTS中愉快地编码。是的,这比我的好。是的,这比我的好。虽然这确实是一个非常好的解决方案,但我实际上不仅要转换标记名和属性,还要转换选定的字符串。所以,遗憾的是,这个解决方案对我不起作用。@Bastibechteld,“但是也选择了字符串。所以,很遗憾,这个解决方案对我不起作用。”这只是因为你不知道怎么做,也因为你没有说这是你在问题中想要做的。实际上,使用解析器可以以一种与我已经演示过的非常类似的方式完成,因为“文本节点”“存在、可访问和可更改。我昨天写了一个答案就是这么做的。虽然这确实是一个很好的解决方案,但我