You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

正则匹配编码兼容错误排查:UTF-8正则与ASCII-8BIT字符串匹配失败

解决Ruby中Encoding::CompatibilityError的编码不匹配问题

这问题我之前写网页爬虫时也踩过一模一样的坑!本质是字符串编码和正则编码不兼容——虽然你确认页面是UTF-8,但HTTP.get返回的响应体默认是以ASCII-8BIT(二进制)格式存储的,而你的正则表达式是UTF-8编码的,两者一匹配就触发了兼容性错误。下面给你分步解决:

核心思路:统一编码 + 修正正则匹配逻辑

首先要把响应体的编码明确为页面实际编码,再转成UTF-8确保和正则编码一致;同时修正正则表达式,因为你之前用的是HTML转义实体&lt;,但网页源码里的标签是原始的<,这也会导致部分匹配失效。

修正后的完整代码

urls.each do |url|
  response = HTTP.get(url)
  if response.status.success?
    # 1. 处理编码:优先从响应头获取页面charset,无则默认UTF-8
    content_type = response.headers['Content-Type'] || ''
    charset = content_type.match(/charset=([^;]+)/) ? $1.strip : 'UTF-8'
    
    # 强制指定编码并转成UTF-8,替换无效/未定义字符避免报错
    source_code = response.body.force_encoding(charset).encode(
      'UTF-8',
      invalid: :replace,
      undef: :replace,
      replace: ''
    )

    # 2. 修正正则:匹配原始HTML标签而非转义实体
    # 移除HTML注释(支持跨行)
    source_code = source_code.gsub(/<!--(.*?)-->/m, '')
    # 移除所有script标签及其内容(兼容大小写和任意属性)
    source_code = source_code.gsub(/<script\b[^>]*>(.*?)<\/script>/mi, '')

    if source_code.match(/out of stock/i)
      # 标记URL做后续处理
      puts "#{url} 检测到缺货提示!"
    end
  end
end

关键细节说明

  • 编码处理:force_encoding只是告诉Ruby二进制字符串的实际编码,encode才是真正把它转成UTF-8;invalid: :replace和undef: :replace能避免页面存在无效字符时抛出异常,让程序更健壮。
  • 正则优化:用<替代&lt;才能匹配源码里的真实标签,\b确保匹配完整的script标签开头(避免误匹配noscript这类相似标签),mi修饰符让匹配忽略大小写且支持跨行内容。
  • 兼容性提升:从响应头提取charset比硬编码UTF-8更靠谱,能自动适配GBK、Shift_JIS等其他编码的页面。

内容的提问来源于stack exchange,提问作者Jordan Lagan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 12:17:29