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

spi*_*rit 7 php regex string invisible character

我在PHP中有字符串,我从数据库中读取.字符串是URL,乍一看它们看起来很好,但最后似乎有一些奇怪的字符.在浏览器的地址栏中,字符串'%E2%80%8E'会附加到URL,从而中断URL.

我发现这篇文章从PHP中的字符串中剥离了从左到右的标记,它似乎与我的问题有关,但解决方案对我不起作用,因为我的角色似乎是别的东西.

那么如何确定我拥有哪个角色,以便将其从字符串中删除?

(我会在这里发布其中一个URL作为示例,但是只要我将其粘贴到此处,堆栈溢出形式就会在最后删除该字符.)

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

编辑:问题已得到解答,接受的答案中给出的代码对我有用:

$str = preg_replace('/\p{C}+/u', "", $str);
Run Code Online (Sandbox Code Playgroud)

Jon*_*y 5 16

如果输入是utf8编码的,可以使用unicode正则表达式匹配/剥离不可见的控制字符,如e2808e(从左到右标记).使用u (PCRE_UTF8) 修饰符\p{C}\p{Other}.

剥去所有隐形:

$str = preg_replace('/\p{C}+/u', "", $str);
Run Code Online (Sandbox Code Playgroud)

这里是一个列表\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>";
}
Run Code Online (Sandbox Code Playgroud)

产出:

detected e2808e @ offset 1
detected e2808b @ offset 5
detected e2808f @ offset 9
Run Code Online (Sandbox Code Playgroud)

在eval.in上测试

要识别,请查看Google,例如fileformat.info:

@谷歌: site:fileformat.info e2808e

  • @jonny 5,一直在寻找这个大约 6 个小时,尝试了各种正则表达式,这就是我一直需要的。非常感谢 (2认同)