首页 > 解决方案 > 使用 preg_match_all 和 UTF-8 正确 PREG_OFFSET_CAPTURE

问题描述

我正在使用 preg_match_all 在字符串中查找所有标签及其位置

preg_match_all('/<\/?([a-zA-Z]+)[^>]*>/', $text, $tags, PREG_SET_ORDER | PREG_OFFSET_CAPTURE);

它适用于 Windows-1251,但是一旦我切换到 UTF-8(并将 /u 添加到正则表达式)

preg_match_all('/<\/?([a-zA-Z]+)[^>]*>/u', $text, $tags, PREG_SET_ORDER | PREG_OFFSET_CAPTURE);

它可以正确识别标签,但会错误计算偏移量。

为了解决这个问题,我尝试转换为 UTF-32

$text32 = mb_convert_encoding($text, 'utf-32', 'utf-8');
preg_match_all('/<\/?([a-zA-Z]+)[^>]*>/', $text32, $tags, PREG_SET_ORDER | PREG_OFFSET_CAPTURE);

这打破了更多,它返回 void$tags数组。

我试图将正则表达式与文本一起转换:

$text32 = mb_convert_encoding($text, 'utf-32', 'utf-8');
preg_match_all(mb_convert_encoding('/<\/?([a-zA-Z]+)[^>]*>/', 'utf-32', 'utf-8'), $text32, $tags, PREG_SET_ORDER | PREG_OFFSET_CAPTURE);

但它现在甚至看不到正则表达式:

  PHP Warning:  preg_match_all(): Null byte in regex

所以我的问题是如何使 preg_match_all 与 UTF-32 一起工作?或者如何修复 UTF-8 编码的不正确偏移量。

PS我尝试了UTF-16,结果相同。PPS php 文件编码为 UTF-8。

标签: phpregexutf-8utf-32

解决方案


推荐阅读