使用PHP正则表达式在字符串中匹配任何Unicode空格字符

4

我希望将文本消息拆分为每个空格的数组。一直运行得很好,直到我收到这条短信。 以下是处理文本字符串的几行代码:

    $str = 'T bw4  05/09/19 07:51 am BW6N 499.803';
    $cleanStr = iconv("UTF-8", "ISO-8859-1", $str);
    $strArr = preg_split('/[\s\t]/', $cleanStr);
    var_dump($strArr);

Var_dump给出的结果如下:

array:6 [▼
 0 => "T"
 1 => b"bw4  05/09/19"
 2 => "07:51"
 3 => "am"
 4 => "BW6N"
 5 => "499.803"
]

数组中的第一项“1 => b”bw4 05/09/19”不正确,我无法弄清楚数组值前面的字母“b”是什么意思。此外,“bw4”和“05/09/19”之间的空格也有问题。如果您有更好的字符串拆分建议,请告诉我。以下是原始字符串:https://3v4l.org/2L35M,这是我的本地主机上结果的图像:http://prntscr.com/jjbvny

你没有看到它吗?https://3v4l.org/TnmK5。你确定你在这里正确地表示了字符串吗? - Phil
这很棘手!当我发布问题时,一些字符可能被过滤掉了。这是原始字符串:https://3v4l.org/2L35M,这是来自我的本地主机的结果图像:http://prntscr.com/jjbvny。 - Guntar
2
可能是字符串字面值前面的b是什么意思?的重复问题。 - Daniel A. White
"array:6 [▼" 不是标准的 var_dump!您是否使用了某个框架或 PHP 扩展程序来提供一些美化的转储? - deceze
@Daniel,问题在于这应该是一个与PHP 6的向前兼容性注释,但PHP 6从未出现。直到今天,二进制字符串和非二进制字符串之间没有区别。而且不清楚是什么在输出这个东西。 - deceze
3个回答

6

要匹配一个或多个Unicode空白字符,可以使用以下方法

'~\s+~u'

你的'/[\s\t]/'模式只匹配一个空格字符(\s)或制表符(\t)(当然,这是多余的,因为\s已经匹配了制表符),但由于缺少u标志,\s不能匹配在bw4之后的\u00A0字符(硬空格)。
所以,请使用:
$str = 'T bw4  05/09/19 07:51 am BW6N 499.803';
$strArr = preg_split('/\s+/u', $str);
print_r($strArr);

查看PHP演示结果。

Array
(
    [0] => T
    [1] => bw4
    [2] => 05/09/19
    [3] => 07:51
    [4] => am
    [5] => BW6N
    [6] => 499.803
)

1

我猜测您的输入未被正确编码。请尝试:

$cleanStr = iconv('UTF-8', 'ISO-8859-1//TRANSLIT', utf8_encode($str));

这个代码会为我清理字符串: https://3v4l.org/d80QS(如果这次正确显示的话)。

注意:这也可能意味着从你的数据库传输过来的编码被损坏了(文本存储在UTF-8中吗?),你的Web服务器(在Apache的httpd.conf文件中是否设置了AddDefaultCharset UTF-8 ?),或者在PHP中(在你的PHP.ini文件中,你的default_charset="utf-8"吗?),网站(<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />),或者在源文件开头有一个BOM(字节顺序标记)?


0

由于您提到值未正确分隔,首先尝试在字符串两端修剪

接下来,将字符串中的多个空格替换为单个空格

$output = preg_replace('!\s+!', ' ', trim($str," "));

之后你可以根据空格进行分割

$fout = explode(" ",$output);

然后你可以打印它。

至于b前缀,@Daniel A. White发布的链接是相关答案。


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