在PHP中确定和删除字符串中的不可见字符 (%E2%80%8E)

12

我在 PHP 中从数据库读取字符串,这些字符串是 URL,乍一看它们看起来很好,但似乎末尾有一些奇怪的字符。在浏览器的地址栏中,字符串“%E2%80%8E”会被附加到 URL 上,导致 URL 错误。

我发现了这篇帖子,介绍了如何在 PHP 中去除字符串中的从左至右标记(left-to-right-mark),它似乎与我的问题有关,但该解决方案对我不起作用,因为我的字符似乎是其他东西。

那么,我该如何确定我有哪个字符,以便从字符串中删除它?

(我想在此贴出其中一个示例 URL,但是当我将其粘贴在 Stack Overflow 表单中时,它就会删除末尾的字符。)

我知道我只能允许字符串中的某些字符并丢弃所有其他字符。但我仍然想知道是哪个字符,以及它是如何进入数据库的。

编辑:问题已得到回答,并且接受的答案中给出的代码对我有效:

$str = preg_replace('/\p{C}+/u', "", $str);

我会使用正则表达式来排除它们。请参见:http://www.roscripts.com/PHP_regular_expressions_examples-136.html - Anthony Horne
你尝试过用户“YOU”的解决方案吗? - Casimir et Hippolyte
@CasimiretHippolyte 谢谢。用户YOU提供的preg_replace版本对我有效,我刚刚尝试了一下。但是它是哪个字符呢?如果它是从右到左的标记,为什么被接受的解决方案不起作用呢? - spirit
1个回答

24
如果输入是utf8编码,可以使用unicode regex匹配/删除不可见的控制字符,例如e2808e(从左到右标记)。使用u(PCRE_UTF8)modifier\ p {C}\ p {Other} 删除所有不可见字符:
$str = preg_replace('/\p{C}+/u', "", $str);

这里是一个列表,其中包含\p{Other}


检测/识别不可见字符:

$str = ".\xE2\x80\x8E.\xE2\x80\x8B.\xE2\x80\x8F";

// get invisibles + offset
if(preg_match_all('/\p{C}/u', $str, $out, PREG_OFFSET_CAPTURE))
{
  echo "<pre>\n";
  foreach($out[0] AS $k => $v) {
    echo "detected ".bin2hex($v[0])." @ offset ".$v[1]."\n";
  }
  echo "</pre>";
}

输出:

detected e2808e @ offset 1
detected e2808b @ offset 5
detected e2808f @ offset 9

在eval.in上进行测试

要识别它,请在Google上查找,例如fileformat.info:

@google:site:fileformat.info e2808e


1
非常感谢,这回答了我的问题。preg_replace 起作用了,并且给出的函数将该字符识别为 e2808e,根据建议的 Google 搜索术语,它确实是 Unicode 字符“从左到右标记”(U+200E)。我已经接受了这个答案。 - spirit
2
@jonny 5,我已经找了6个小时了,尝试了各种正则表达式,但最终发现这就是我一直需要的。非常感谢你。 - Andrew Killen
这也将去除软连字符,但根据上下文,它们的主要目的是用于输出原因。 - AmigoJack

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接