PHP mb_split(),捕获分隔符

时间:2015-06-02 19:42:04

标签: php delimiter capture preg-split multibyte

PREG_SPLIT_DELIM_CAPTURE有一个可选的mb_split标志,它还返回返回数组中的所有分隔符。 /** * A cross between mb_split and preg_split, adding the preg_split flags * to mb_split. * @param string $pattern * @param string $string * @param int $limit * @param int $flags * @return array */ function mb_explode($pattern, $string, $limit = -1, $flags = 0) { $strlen = strlen($string); // bytes! mb_ereg_search_init($string); $lengths = array(); $position = 0; while (($array = mb_ereg_search_pos($pattern)) !== false) { // capture split $lengths[] = array($array[0] - $position, false, null); // move position $position = $array[0] + $array[1]; // capture delimiter $regs = mb_ereg_search_getregs(); $lengths[] = array($array[1], true, isset($regs[1]) && $regs[1]); // Continue on? if ($position >= $strlen) { break; } } // Add last bit, if not ending with split $lengths[] = array($strlen - $position, false, null); // Substrings $parts = array(); $position = 0; $count = 1; foreach ($lengths as $length) { $is_delimiter = $length[1]; $is_captured = $length[2]; if ($limit > 0 && !$is_delimiter && ($length[0] || ~$flags & PREG_SPLIT_NO_EMPTY) && ++$count > $limit) { if ($length[0] > 0 || ~$flags & PREG_SPLIT_NO_EMPTY) { $parts[] = $flags & PREG_SPLIT_OFFSET_CAPTURE ? array(mb_strcut($string, $position), $position) : mb_strcut($string, $position); } break; } elseif ((!$is_delimiter || ($flags & PREG_SPLIT_DELIM_CAPTURE && $is_captured)) && ($length[0] || ~$flags & PREG_SPLIT_NO_EMPTY)) { $parts[] = $flags & PREG_SPLIT_OFFSET_CAPTURE ? array(mb_strcut($string, $position, $length[0]), $position) : mb_strcut($string, $position, $length[0]); } $position += $length[0]; } return $parts; } 没有。

有没有办法拆分多字节字符串(不只是UTF-8,而是所有类型)并捕获分隔符?

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

解决方案 感谢用户Casimir et Hippolyte,我构建了一个解决方案并将其发布在github上 (https://github.com/vanderlee/PHP-multibyte-functions/blob/master/functions/mb_explode.php),它允许所有preg_split标志:

    def main(argv):
        app = DestinyManager(sys.argv)
        engine = QtQml.QQmlEngine(app)
        engine.quit.connect(app.quit)
        ...

1 个答案:

答案 0 :(得分:2)

只能使用std::wstring_convert捕获分隔符,并且在其他函数中不可用。

三种可能性:

1)将您的字符串转换为UTF8,将preg_splitpreg_split一起使用,并使用PREG_SPLIT_DELIM_CAPTURE将每个项目转换为原始编码。

这种方式更简单。第二种方式并非如此。 (请注意,一般来说,总是在UTF8中工作更简单,而不是处理异国情调的编码)

2)代替类似分割的函数,您需要使用例如mb_ereg_search_regs来获取匹配的部分并构建像这样的模式:

array_map

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

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

mb_split

(这种方式的局限在于,lookbehind中的子模式不能有可变长度(换句话说,你不能在里面使用量词),但它可以是固定长度的交替子模式:(?=delimiter)|(<=delimiter)