正则表达式只从字符串中删除开始和结束的html标记?

时间:2012-06-10 01:54:07

标签: ruby-on-rails ruby regex

我想从下面的字符串中删除例如<div><p></p></div>。正则表达式应该能够从字符串的开头和结尾删除任意数量的标记。

<div><p>text to <span class="test">test</span> the selection on.
Kibology for <b>all</b><br>. All <i>for</i> Kibology.</p></div>

我一直在修改rubular.com但没有成功。谢谢!

4 个答案:

答案 0 :(得分:1)

 def remove_html_end_tags(html_str)
   html_str.match(/\<(.+)\>(?!\W*\<)(.+)\<\/\1\>/m)[2]
 end

我没有看到 \&lt;(。+)&gt; 消耗Alan Moore在下面指出的多个开场代码的问题,这很奇怪,因为我同意这是不正确的。它应该更改为 \&lt;([^&gt; \&lt;] +)&gt; 或类似的消除歧义。

 def remove_html_end_tags(html_str)
    html_str.match(/\<([^\>\<]+)\>(?!\W*?\<)(.+)\<\/\1\>/m)[2]
 end

这个想法是你要捕获所遇到的第一个标记的打开/关闭之间的所有内容,而不是紧跟另一个标记,即使之间有空格。

因为我不确定如何(带有正向前瞻性)说给我第一把关键角括号在下一个开口角括号之前至少跟一个字符后面的键,我说

\>(?!\W*\<)

找到在下一个打开的尖括号之前没有所有非单词字符的结束尖括号。

一旦你确定了具有该属性的密钥,找到它的结束配合并返回它们之间的东西。

这是另一种方法。找到向前扫描的标签并删除第一个n。会破坏相同类型的嵌套标签,但我不会将这种方法用于任何实际工作。

def remove_first_n_html_tags(html_str, skip_count=0)
  matches = []
  tags = html_str.scan(/\<([\w\s\_\-\d\"\'\=]+)\>/).flatten  
  tags.each do |tag|
   close_tag = "\/%s" % tag.split(/\s+/).first
   match_str = "<#{tag}>(.+)<#{close_tag}>"
   match = html_str.match(/#{match_str}/m) 
   matches << match if match
 end
 matches[skip_count]

答案 1 :(得分:0)

还涉及一些编程:

str = '<div><p>text to <span class="test">test</span> the selection on.
Kibology for <b>all</b><br>. All <i>for</i> Kibology.</p></div>'

while (m = /\A<.+?>/.match(str)) && str.end_with?('</' + m[0][1..-1])
  str = str[m[0].size..-(m[0].size + 2)]
end
你在那儿克苏鲁吗?

答案 2 :(得分:-1)

(?:\<div.*?\>\<p.*?\>)|(?:\<\/p\>\<\/div\>)是您需要的表达方式。但是这并没有检查每个场景......如果你试图解析任何可能的标签组合,你可能想看看其他解析方法。

例如,此表达式不允许div和p标记之间的任何空格。因此,如果您想要允许,可以在标记的\s*部分之间添加\>\<,如下所示:(?:\<div.*?\>\s*\<p.*?\>)|(?:\<\/p\>\s*\<\/div\>)

在写入表达式时,div标签和p标签应该是小写的。因此,您可能想要找出一种方法来检查每个字母的大写或小写字母,以便也可以找到Div或dIV。

使用gskinner's RegEx tool测试和学习正则表达式。

所以你的最终ruby代码应该是这样的:

# Ruby sample for showing the use of regular expressions

str = "<div><p>text to <span class=\"test\">test</span> the selection on.
Kibology for <b>all</b><br>. All <i>for</i> Kibology.</p></div>"

puts 'Before Reguar Expression: "', str, '"'

str.gsub!(/(?:\<div.*?\>\s*\<p.*?\>)|(?:\<\/p\>\s*\<\/div\>)/, "")

puts 'After Regular Expression', str

system("pause")

编辑:将div*?替换为div.*?,并根据评论中的建议将p*?替换为p.*?。 编辑:这个答案不允许任何标签集,只是问题第一行中列出的两个标签。

答案 3 :(得分:-1)

我将继续回答我自己的问题。以下是程序化路线:

输入字符串作为数组进入第一个循环,以便删除前标记。生成的字符串以相反的顺序循环,以便删除结束标记。然后反转该字符串以使其按正确的顺序排列。

def remove_html_end_tags(html_str)

 str_no_start_tag = ''
 str_no_start_and_end_tag = ''

  a = html_str.split("")

     i= 0 
     is_text = false
     while i <= (a.length - 1)
       if (a[i] == '<') && !is_text
         while (a[i] != '>')
           i+= 1
         end 
          i+=1
       else
         is_text = true
          str_no_start_tag << a[i] 
         i+=1
       end
     end

    a = str_no_start_tag.split("")

    i= a.length - 1 
    is_text = false
    while i >= 0
      if (a[i] == '>') && !is_text
        while (a[i] != '<')
           i-= 1
        end 
        i-=1
      else
        is_text = true
        str_no_start_and_end_tag << a[i] 
        i-=1
      end
   end 

  str_no_start_and_end_tag.reverse!

 end