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
标志和限制。