Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/heroku/2.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 mb_split(),捕获分隔符_Php_Delimiter_Capture_Preg Split_Multibyte - Fatal编程技术网

PHP mb_split(),捕获分隔符

PHP mb_split(),捕获分隔符,php,delimiter,capture,preg-split,multibyte,Php,Delimiter,Capture,Preg Split,Multibyte,preg_split有一个可选的preg_split_DELIM_CAPTURE标志,它还返回返回数组中的所有分隔符mb_分割不会 有没有办法拆分一个多字节字符串(不仅仅是UTF-8,还有各种类型)并捕获分隔符 我正在尝试制作一个多字节安全的换行符拆分器,保留换行符,但更喜欢更通用的解决方案 解决方案 感谢用户Casimir et Hippolyte,我构建了一个解决方案,并将其发布在github上 (),它允许所有preg_分割标志: /** *mb_split和preg_split之间的交叉

preg_split
有一个可选的
preg_split_DELIM_CAPTURE
标志,它还返回返回数组中的所有分隔符<代码>mb_分割不会

有没有办法拆分一个多字节字符串(不仅仅是UTF-8,还有各种类型)并捕获分隔符

我正在尝试制作一个多字节安全的换行符拆分器,保留换行符,但更喜欢更通用的解决方案

解决方案 感谢用户Casimir et Hippolyte,我构建了一个解决方案,并将其发布在github上 (),它允许所有preg_分割标志:

/**
*mb_split和preg_split之间的交叉,添加preg_split标志
*要分开。
*@param字符串$pattern
*@param string$string
*@param int$limit
*@param int$flags
*@return数组
*/
函数mb_explode($pattern,$string,$limit=-1,$flags=0){
$strlen=strlen($string);//字节!
mb_ereg_search_init($string);
$length=array();
$position=0;
while(($array=mb\u ereg\u search\u pos($pattern))!==false){
//捕捉分裂
$length[]=数组($array[0]-$position,false,null);
//移动位置
$position=$array[0]+$array[1];
//捕获定界符
$regs=mb_ereg_search_getregs();
$length[]=array($array[1],true,isset($regs[1])&&$regs[1]);
//继续吗?
如果($position>=$strlen){
打破
}           
}
//如果不是以拆分结尾,则添加最后一位
$length[]=数组($strlen-$position,false,null);
//子串
$parts=array();
$position=0;
$count=1;
foreach($length作为$length){
$is_分隔符=$length[1];
$is_captured=$length[2];
如果($limit>0&!$是分隔符($length[0]| | ~$flags&PREG\u SPLIT\u NO\u EMPTY)&&++$count>$limit){
如果($length[0]>0 | | ~$flags&PREG_SPLIT_NO_EMPTY){
$parts[]=$flags&PREG\u SPLIT\u OFFSET\u CAPTURE
?阵列(mb_struct($string,$position),$position)
:mb_struct($string,$position);
}
打破
}elseif(!$is|分隔符($flags&PREG|u SPLIT\u DELIM|u CAPTURE&$is|u CAPTURE))
&&($length[0]| | ~$flags&PREG_SPLIT_NO_EMPTY)){
$parts[]=$flags&PREG\u SPLIT\u OFFSET\u CAPTURE
?数组(mb_struct($string,$position,$length[0]),$position)
:mb_struct($string,$position,$length[0]);
}
$position+=$length[0];
}
退回$parts;
}

捕获分隔符仅在
preg\u split
中可用,在其他功能中不可用

因此有三种可能性:

1)将字符串转换为UTF8,使用
preg\u split
preg\u split\u DELIM\u CAPTURE
将每个项目转换为原始编码

这种方法更简单。第二种情况并非如此。(请注意,一般来说,始终使用UTF8比处理外来编码更简单)

2)例如,您需要使用类似分割的函数来获取匹配的零件并构建如下模式:

delimiter|all_that_is_not_the_delimiter
(请注意,交替的两个分支必须相互排斥,并注意以不可能在结果之间产生间隙的方式写入它们。第一部分必须在字符串的开头,最后一部分必须在末尾。每个部分必须与前一部分相邻,依此类推。)

3)使用
mb_分割
。根据定义,lookarounds是零宽度断言,不匹配任何字符,只匹配字符串中的位置。因此,您可以使用这种模式来匹配分隔符之后或之前的位置:

(?=delimiter)|(<=delimiter)

(?=delimiter)|(您想做什么?发布一个示例字符串。我想用它来拆分换行符上的行。方法3运行良好:
mb_拆分('(?=\r\n |\r |\n)|(@Martijn:如果换行序列是
\r\n
,这种方法将不起作用,因为模式将在
\r
\n
处拆分。因此您将获得:
\r
\n
。在这种情况下,方法2)更合适,因为您可以简单地使用此模式:
[^\r\n]+|\r?\n |\r
好吧,这在我的测试中似乎是可行的,但是还有一个问题,PHP5.2和5.3抛出了一个错误,因为他们认为模式是空的。接下来我将研究解决方案2。我想我找到了一个解决方案,使用了受方法2启发的东西(但改用
mb_ereg\u search\u pos
).Pastebin:它没有经过彻底测试,但初步测试似乎很好;支持所有
preg_split
标志和限制。