【问题标题】:Ruby Regex matching string before and after certain charactersRuby Regex 在某些字符之前和之后匹配字符串
【发布时间】:2010-02-24 14:38:30
【问题描述】:

我有一个这样的字符串:

<block trace="true" name="AssignResources: Append Resources">

我需要在<(在本例中为block)和=(这里 tracename)。

我尝试了几种正则表达式模式,但我所有的尝试都返回了包含“分隔符”字符的单词......比如;block

我确信这并不难,但我还没有找到解决方案。

有人有提示吗?
谢谢。

顺便说一句:我想用gsub替换模式匹配。

编辑:

用以下正则表达式解决它:

1) /\s(\w+)="(.*?)"/ 匹配 $1 和 $2 中的所有 attr 及其值。

2) /<!--.*-->/ 匹配 cmets

3) /<([\/|!|\?]?)([A-Za-z0-9]+)[^\s|>|\/]*/ 匹配所有标签名称,无论它们是在结束标签、自结束标签、<?xml>-tag 还是 DTD-tag 中。 $1 包含可选的前缀 / ! or ? 或什么都没有,$2 包含标记名

【问题讨论】:

    标签: ruby regex


    【解决方案1】:

    在我看来,它很像parsing HTML with regex

    Ruby 有一个非常好的 html 解析器,叫做 Nokogiri

    这里是如何做的

    require 'nokogiri'
    
    html=Nokogiri::HTML('<block trace="true" name="AssignResources: Append Resources">')
    
    html.xpath("//*").each do |s|
        puts s.node_name #block
        puts s.keys #trace, name
        puts s.values #true, AssignResources: Append Resources
    end
    

    【讨论】:

    • 嘿 S.Mark,我已经为此使用了 Nokogiri(XML 解析),它很棒。我会再次考虑我的申请流程——也许我可以更早地使用 nokogiri 进行替换。在我进行替换时,它不再是 XML。它被转换成一个巨大的字符串。这是必要的,因为它应该以文本形式呈现,其前 xml-tag 属性的值是链接到其他 html 页面的 html -tags,由该属性的值定义。通过 gsub 和模式匹配的替换是用不同的 -tags. 包围 xml 标签的一部分
    • 不:在这种情况下,通过 javascript 进行语法高亮显示不是解决方案。此刻我已经使用了“美化”。但是拥有超过 2000 行和 x 倍多的标签的文档,使用起来并不有趣。这就是为什么我想在我的解析应用程序中准备输出。
    • 语法高亮?您是否考虑过使用像 shjs 这样的现有库? shjs.sourceforge.net
    • 是的,我试过了,正如我所说,使用 Prettify (code.google.com/p/google-code-prettify)。我认为问题是一样的:要突出显示大量内容,该站点不再可用(30 秒以上)。巨大的内容 => 7000 多行 xml 有时奇怪的要求要求奇怪的解决方案;)
    • 我认为正则表达式不能快速处理 7000 多行数据。
    【解决方案2】:

    你可以试试:

    &lt;([^ ]*)\s([^=]*)=
    

    【讨论】:

      【解决方案3】:
      '&lt;block trace="true" name="AssignResources: Append Resources"&gt;'[/&lt;(\w+)/, 1]
      #=> "block"
      

      如果您将正则表达式和索引 i 传递给 String#[],它将返回第 i 个捕获组的值。

      编辑:

      在 1.9 中,您可以使用 /(?&lt;=&amp;lt;)\w+/ 来要求 &amp;lt; 存在而不匹配它。在 1.8 中没有办法做到这一点。您可以做的最好的事情是将不想替换的部分放在捕获组中,然后在替换中访问该组,如下所示:

      "lo&lt;la li".gsub(/(&lt;)(\w+)/, '\1 --\2--')
       #=> "lo&lt; --la-- li"
      

      【讨论】:

      • 感谢您的提示,但我需要正则表达式模式作为 gsub 方法的参数,以将所有这些模式匹配替换为另一个字符串。我正在考虑如何让它适合 gsub。
      【解决方案4】:
      &lt;block trace="true" name="AssignResources: Append Resources"&gt;
      
      &lt;([^\s]+)\s+([^=]+)="([^"]*)"\s+([^=]+)="([^"]*)"\s*&gt;
      
      #result:
      
      $1 block
      $2 trace
      $3 true
      $4 name
      $5 AssignResources: Append Resources
      

      更新:我不知道 ruby​​,但根据gsub here 的描述,我相信类似下面的东西应该可以解决问题。

      str = '&lt;block trace="true" name="AssignResources: Append Resources"&gt;'
      repl = str.gsub(/&lt;([^\s]+)\s+([^=]+)="([^"]*)"\s+([^=]+)="([^"]*)"\s*&gt;/, 
          "tag name: \\1\n\\2 is \\3 and \\4 is \\5\n")
      print repl
      

      【讨论】:

      • 感谢 Amarghosh,非常好的解决方案,但我忘了说,我需要它作为 gsub 的模式参数......但无论如何,谢谢。
      【解决方案5】:

      您很可能应该选择 Nokigiri 或类似的东西。 我无法将它放在一个 gsub 中,而是放在两个中:

      >> m,r=0,["&lt;blockie ", " tracie=", " namie="]
      >> s.gsub(/&lt;.*?([^\s]+)\s/, r[0]).gsub(/\s([^=]+)=/) {|ma| m+=1; r[m]}
      => "&lt;blockie tracie="true" namie="AssignResources: Append Resources"&gt;"
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-01-05
        • 1970-01-01
        • 2014-11-24
        • 1970-01-01
        • 2018-06-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多