Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/246.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在PHP中基于unicode字符范围将字符串拆分为数组_Php_Arrays_Regex_Unicode_Split - Fatal编程技术网

在PHP中基于unicode字符范围将字符串拆分为数组

在PHP中基于unicode字符范围将字符串拆分为数组,php,arrays,regex,unicode,split,Php,Arrays,Regex,Unicode,Split,很抱歉,主题不明确,我要找的是一个包含西里尔字母的字符串 «Добрый день!» - сказал он, потянувшись… 进入一个数组 [0] => « [1] => Добрый␠ [2] => день!»␠-␠ [3] => сказал␠ [4] => он,␠ [5] => потянувшись… 所以本质上,我在寻找任何字符和西里尔字母字符([а-а]范围)之间的边界上出现的中断,尽管这只有在我们从任何字符过渡到西里尔字母字

很抱歉,主题不明确,我要找的是一个包含西里尔字母的字符串

«Добрый день!» - сказал он, потянувшись…
进入一个数组

[0] => «
[1] => Добрый␠
[2] => день!»␠-␠
[3] => сказал␠
[4] => он,␠
[5] => потянувшись…
所以本质上,我在寻找任何字符和西里尔字母字符([а-а]范围)之间的边界上出现的中断,尽管这只有在我们从任何字符过渡到西里尔字母字符时才是真的,反之亦然。我见过一些例子,它们成功地用标点符号和拉丁字母来解决这个问题

preg_split('/([^.:!?]+[.:!?]+)/', 'hello:there.everyone!so.how?are:you', NULL, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY );
但到目前为止,我试图将其重新定位为不同的东西的尝试失败了:

preg_split ('/(?<=[^а-я])/ius', $text, NULL, PREG_SPLIT_NO_EMPTY);

preg_split('/(?您还必须提前检查下一个字符是否为cyrrilic字符。此代码将完成以下工作:

$t = preg_split ('/(?<=[^а-я])(?=[а-я]+)/ius', $text, NULL, PREG_SPLIT_NO_EMPTY);

试试这个正则表达式:。从0400到04FF的所有unicode字符都被认为是西里尔字母。它应该完全符合您的要求。您还可以按照另一个答案中的建议,将
\x{0400}-\x{04FF}
替换为
\p{西里尔字母}

这是该范围内的所有字符:

ЀЁЂЃЄЅІЇЈЉЊЋЌЍЎЏ0АБВГДЕЖЗИЙКЛМНОП0РСТУФХЦЧШЩЪЫЬЭЮЯ0абвгдежзийклмнопрстуфхцчшщъыьэюяѐёђѓєѕіїјљњћќѝўџ0460ѠѡѢѣѤѥѦѧѨѩѪѫѬѭѮѯѰѱѲѳѴѵѶѷѸѹѺѻѼѽѾѿҀҁ҂҃҄҅҆҇҈҉ҊҋҌҍҎҏҐґҒғҔҕҖҗҘҙҚқҜҝҞҟҠҡҢңҤҥҦҧҨҩҪ此外,本月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月月使用以下溶液:

$s = "«Добрый день!» - сказал он, потянувшись…";
$res = preg_split('/\b(\p{Cyrillic}+\W*)/u', $s, NULL, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
print_r($res);
// Array(
//   [0] => «
//   [1] => Добрый 
//   [2] => день!» - 
//   [3] => сказал 
//   [4] => он, 
//   [5] => потянувшись…
//)

详细信息

  • \b(\p{Cyrillic}+\W*)
    -匹配并捕获一个完整的Cyrillic单词,后面有0+个非单词字符
  • 模式用捕获括号括起来,
    PREG\u SPLIT\u DELIM\u CAPTURE
    将捕获的值推送到结果数组中
  • PREG\u SPLIT\u NO\u EMPTY
    将丢弃数组中的空值
  • /u
    修饰符将使
    \b
    (单词边界)和
    \W
    识别Unicode,并允许使用正则表达式处理Unicode字符串

以开头的形式拆分如何

确保
\b
后跟一个。
(?!^)
防止空匹配


为什么
«
字符被捕获为一个单独的项目,而相同的对立面
»
被捕获为字符串的一部分。
?是的,这不是最好的例子,我愿意牺牲[0]不知为什么。我真的很喜欢这个优雅的解决方案,但当我在自己的PHP中尝试它时,我得到的只是一行,没有拆分。但它在您的演示中确实有效。为什么会这样呢?当我尝试它时,这个正则表达式会丢失所有其他单词,只有奇数个单词进入数组,偶数个单词也会丢失。不要将其与拆分一起使用,将其与匹配一起使用。这与字符串不是一个可以拆分的位置。谢谢你,但我认为你也应该检查bobble bubble的答案,这个答案似乎更优雅一些。你已经投票赞成了。另一个变体:相同的故事。我的PHP不尊重某些东西(尽管我不明白为什么它会这样做)而且只有先行变量起作用。这是一个逻辑解决方案,但不幸的是,我需要仅在西里尔字母字符上出现中断,以便,例如,“ааааааааа单词”不会被拆分为两个。@ааааааJoe在这种情况下,您可以尝试一下。我刚刚尝试了您提供出于某种原因,在这两种情况下都只返回一个数组元素。@X3ааааааааJoe可能有相同的问题,Wiktor的答案类似。可能是这样,而且有点令人困惑。我确实设置了mbаU内部аU编码('UTF-8');我认为它不需要任何其他技巧。想知道什么坏了,哪里坏了。
$s = "«Добрый день!» - сказал он, потянувшись…";
$res = preg_split('/\b(\p{Cyrillic}+\W*)/u', $s, NULL, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
print_r($res);
// Array(
//   [0] => «
//   [1] => Добрый 
//   [2] => день!» - 
//   [3] => сказал 
//   [4] => он, 
//   [5] => потянувшись…
//)
$res = preg_split('/\b(?=\w)(?!^)/u', $str);