正则表达式,用于仅从字符串中删除开始和结束 html 标记



我想从下面的字符串中删除例如<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 但没有成功。谢谢!

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

我没有看到 \<(.+)>消耗 Alan Moore 下面指出的多个开始标签的问题,这很奇怪,因为我同意这是不正确的。它应该更改为 \<([^>\<]+)> 或类似于消除歧义的内容。

 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(/<([ws_-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]

结束

仍然涉及一些编程:

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

克苏鲁你在外面?

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

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

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
(?:<div.*?><p.*?>)|(?:</p></div>)

你需要的表达式。 但这并不能检查每个场景...如果您尝试解析任何可能的标签组合,您可能需要查看其他解析方法。

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

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

使用 gskinner 的 RegEx 工具来测试和学习正则表达式。

所以你的 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.*?。编辑:此答案不允许任何一组标签,只允许问题第一行中列出的两个标签。

最新更新