【问题标题】:Make encoding uniform before comparing strings in PHP在比较 PHP 中的字符串之前使编码统一
【发布时间】:2009-10-13 20:22:55
【问题描述】:

我正在开发一项功能,该功能需要我获取网页内容,然后检查该页面中是否存在某些文本。这是一个反向链接检查工具。

问题是这样的——该函数大部分时间都运行良好,但偶尔,当链接明显存在时,它会标记一个没有链接的页面。我已经追踪到可以直观地比较输出中的字符串,它们匹配得很好,但是使用 == 运算符,PHP 告诉我它们不匹配。

认识到这可能是某种编码问题,我决定看看如果我在它们上使用base64_encode() 会发生什么,所以我可以看看这样做是否会在两个字符串之间产生不同的结果(这似乎完全一样)。

我的怀疑得到了证实——在要比较的字符串上使用 base64_encode 会产生不同的字符串。问题找到了!

有没有什么方法可以根据输出的文本(匹配的)使这些字符串统一,这样当我在 PHP 中比较它们时,它们匹配?

【问题讨论】:

  • 您能否可靠地检查您正在比较的网站的字符编码?

标签: php string comparison character-encoding


【解决方案1】:

我并不完全相信你认为它是编码。 PHP 将以相同的格式在内部存储它的所有字符串。

你能试试这个代码吗?它将比较两个字符串中每个字符的 ASCII 值,这可能会通过直观地比较字符串来揭示您看不到的东西。

$str1 = ...;
$str2 = ...;

if(strlen($str1) != strlen($str2)) {
  echo "Lengths are different!";
} else {
  for($i=0; $i < strlen($str1); $i++) {
    if(ord($str1[$i]) != ord($str2[$i]) {
      echo "Character $i is different! str1: " . ord($str1[$i]) . ", str2: " . ord($str2[$i]);
      break;
    }
  }
}

【讨论】:

  • 好吧,这就是我,羞愧地低着头。我正在比较的字符串之一在 2 个单词之间有两个空格。当然,当 html 呈现时,它不会连续显示 2 个空格,所以在我查看源代码之前,字符串似乎完美匹配(根据 firefox 搜索工具,确实匹配完美)。感谢大家的好答案,对不起,真正的必须如此简单......
【解决方案2】:

没有应用程序代码,很难说发生了什么。

尝试在字符串上使用trim() 来删除肉眼看不到的尾随空格。

您可能会发现strcmp 也提供了更好的结果。

【讨论】:

  • 我正在使用 trim 和 strtolower 来确保字符串匹配。 strcmp 返回 -1。我会发布源代码,但我不确定它会有所帮助 - 比较位非常正常,要查看其余代码(获取和解析页面的位置),我会粘贴一千代码行。
  • 您必须逐字节检查字符串以了解它们为何不同。像 iconv 这样的东西可能是获得统一编码的最佳方式。
  • 您对使用 trim() 的建议让我摆脱了 4 小时的困境。谢谢!
【解决方案3】:

通过清理过滤器运行这两个过滤器(如果您的 PHP 版本高于 5.2.0)。我不知道它会做什么,但它可能会。

http://www.phpro.org/tutorials/Filtering-Data-with-PHP.html#12

【讨论】:

  • 链接已损坏(域名已过期 - "NameBright - Coming Soo")。
【解决方案4】:

【讨论】:

    【解决方案5】:

    您可以尝试将DOM extension 用于PHP。在创建新的DOM document 时,您可以指定底层文档/网页的编码。

    根据this website,内部一切都以UTF-8 完成。然后您可以找到您感兴趣的 DOM 节点,并比较 text content of the node

    如果您没有使用带有相关指定字符编码的网页,我建议您使用multibyte 函数,尤其是mb_detect_encodingmb_convert_encoding

    【讨论】:

      【解决方案6】:

      如果不能可靠地获取编码,可以使用mb_convert_encoding

      $string1 = mb_convert_encoding($string1, 'utf-8', 'auto');
      $string2 = mb_convert_encoding($string2, 'utf-8', 'auto');
      

      如果您可以确定编码(从 HTTP 标头或元标记),则应指定编码而不是使用“自动”。

      $string1 = mb_convert_encoding($string1, 'utf-8', $encoding1);
      $string2 = mb_convert_encoding($string2, 'utf-8', $encoding2);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-01-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多