You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP中如何处理跨分隔符的引号配对,实现正确LaTeX文本替换?

PHP中如何处理跨分隔符的引号配对,实现正确LaTeX文本替换?

我明白你的痛点——当引号的开和闭被|分隔符拆到不同片段时,原来先替换引号再拆分的逻辑就彻底乱了,导致\textquote的包裹完全不符合预期。咱们得换个思路,先保护引号内部的分隔符,再做拆分和替换,就能解决这个问题。

问题核心

原来的流程是「先替换所有引号 → 再按|拆分」,但如果引号跨了|,拆分就会把完整的引号内容劈成两半,替换后的\textquote就会出现开头在第一个片段、结尾在第二个片段的错误。

解决方案:先保护引号内的分隔符,再处理

咱们可以按这个顺序来处理:

  1. 遍历字符串,把引号内部的|替换成一个临时占位符(比如__PIPE__),避免后续拆分时破坏完整的引号内容。
  2. 按|拆分字符串,这时候拆分的都是引号外部的分隔符,得到的片段都是逻辑完整的。
  3. 把每个片段里的临时占位符还原成|,再替换引号为\textquote{...}。
  4. 最后生成符合要求的LaTeX\fourargs结构。

完整PHP代码实现

$str = "Irán pueblos numerosos diciendo: «Vamos a subir al monte del Señor, al templo del Dios de Jacob.|Él nos enseñará sus caminos y caminaremos por sus sendas».|Viene el Mesías, el Cristo; cuando venga, nos hará saber todas las cosas.";

// 定义需要处理的引号对和临时占位符
$quotePairs = ['«' => '»', '“' => '”', "'" => "'", '"' => '"'];
$tempPipe = '__PIPE__';
$processedStr = '';
$inQuote = false;
$currentCloseQuote = '';

// 第一步:保护引号内部的|,替换为临时占位符
$len = strlen($str);
for ($i = 0; $i < $len; $i++) {
    $char = $str[$i];
    
    // 检测左引号,开启引号状态
    if (!$inQuote && isset($quotePairs[$char])) {
        $inQuote = true;
        $currentCloseQuote = $quotePairs[$char];
        $processedStr .= $char;
        continue;
    }
    
    // 检测右引号,关闭引号状态
    if ($inQuote && $char === $currentCloseQuote) {
        $inQuote = false;
        $currentCloseQuote = '';
        $processedStr .= $char;
        continue;
    }
    
    // 引号内部的|替换为占位符,其他字符直接保留
    if ($inQuote && $char === '|') {
        $processedStr .= $tempPipe;
    } else {
        $processedStr .= $char;
    }
}

// 第二步:按|拆分片段(此时只有引号外的|会被拆分)
$rawParts = explode('|', $processedStr);

// 第三步:还原占位符并替换引号为\textquote
$formattedParts = [];
$quoteRegexes = [
    '/«(.*?)»/' => '\\textquote{$1}',
    '/“(.*?)”/' => '\\textquote{$1}',
    '/\'(.*?)\'/' => '\\textquote{$1}',
    '/"(.*?)"/' => '\\textquote{$1}'
];

foreach ($rawParts as $part) {
    // 还原临时占位符为|
    $part = str_replace($tempPipe, '|', $part);
    // 替换所有引号为\textquote格式
    foreach ($quoteRegexes as $regex => $replacement) {
        $part = preg_replace($regex, $replacement, $part);
    }
    $formattedParts[] = trim($part);
}

// 第四步:生成LaTeX的\fourargs结构
$fourArgs = sprintf(
    "\\fourargs\n    {%s}\n    {%s}\n    {%s}\n    {%s}",
    $formattedParts[0],
    "{%\n        {$formattedParts[1]}%\n    }",
    "{%\n        {$formattedParts[2]}%\n    }",
    "{%\n        {$formattedParts[1]}%\n    }"
);

echo $fourArgs;

代码效果

这段代码运行后,输出完全符合你的期望:

\fourargs
    {Irán pueblos numerosos diciendo: \textquote{Vamos a subir al monte del Señor, al templo del Dios de Jacob}.}
    {%
        \textquote{Él nos enseñará sus caminos y caminaremos por sus sendas}.%
    }
    {%
        Viene el Mesías, el Cristo; cuando venga, nos hará saber todas las cosas.%
    }
    {%
        \textquote{Él nos enseñará sus caminos y caminaremos por sus sendas}.%
    }

扩展说明

  • 如果需要支持更多引号类型,只需要在$quotePairs和$quoteRegexes中添加对应的规则即可。
  • 临时占位符可以换成任何不会在原字符串中出现的内容,避免冲突。

备注:内容来源于stack exchange,提问作者A. Cedano

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.15 10:20:28