【问题标题】:How to make the function work for pair words?如何使该功能适用​​于成对词?
【发布时间】:2017-10-27 15:29:50
【问题描述】:

我的函数现在只能使用一个单词。例如,我在关联数组中有单词。我的函数用它在文本中的值替换了数组键。以及保持单词小写的功能,但是当您替换单词时,它将返回写入文本的传入单词寄存器。现在该功能不能使用成对的词来用其他成对的词替换成对的词。

示例:

// Function:

function replaceKeyToValue($request, $dict){
    $response = preg_replace_callback("/\pL+/u", function ($m) use ($dict) {
        $word = mb_strtolower($m[0]);
        if (isset($dict[$word])) {
            $repl = $dict[$word];
            // Check for some common ways of upper/lower case
            // 1. all lower case
            if ($word === $m[0]) return $repl;
            // 2. all upper case
            if (mb_strtoupper($word) === $m[0]) return mb_strtoupper($repl);
            // 3. Only first letters are upper case
            if (mb_convert_case($word,  MB_CASE_TITLE) === $m[0]) return mb_convert_case($repl,  MB_CASE_TITLE);
            // Otherwise: check each character whether it should be upper or lower case
            for ($i = 0, $len = mb_strlen($word); $i < $len; ++$i) {
                $mixed[] = mb_substr($word, $i, 1) === mb_substr($m[0], $i, 1) 
                    ? mb_substr($repl, $i, 1)
                    : mb_strtoupper(mb_substr($repl, $i, 1));
            }
            return implode("", $mixed);
        }
        return $m[0]; // Nothing changes
    }, $request);
    return $response;
 }

    // Example associative array

    $dict = array
    (
      "make"=>"take",
      "cool"=>"pool",
      "узбек"=>"ӯзбек",
    );

    $text = 'Make COOL узБЕК';

    echo replaceKeyToValue($text, $dict);

输出:

Take POOL ӯзБЕК

如何重做该功能,使其也可以将单词配对成对词?

带有成对单词的数组示例:

$array = array
(
  "take pool" => "pool take", 
  "get book" => "set word", 
  "узбек точик" => "ӯзбек тоҷик"
);

$example_text = "Take POOL Get BooK УзБеК ТоЧИК";

【问题讨论】:

  • 我 tried the code 但我得到 Make COOL узБЕК 作为输出。
  • 如果@WiktorStribiżew 没有答案,就没有答案:)
  • 最后的return 声明应为return $response;
  • 如果您有{ "A" =&gt; "ax", "B" =&gt; "bx", "A B" =&gt; "aa bb", "B A" =&gt; "x y" },那么您希望输入“A B A B A B A”变成什么?
  • 尝试用"/(?&lt;!\w)(?:" . implode('|', array_keys($dict)) . ")(?!\w)/iu"替换正则表达式

标签: php regex utf-8 case-insensitive preg-replace-callback


【解决方案1】:

第一件事:将您的案例转换排除在问题之外并编写一个专用函数来处理它。

关于单词对:您可以使用以下方法解决问题:

  • 带有可选子模式以捕获第二个单词的前瞻
  • 一个静态布尔变量(在回调函数中定义),用于了解上一个匹配项是否是现有两个单词子字符串的第一个单词。

你只需要这个模式:

~\b\pL+\b(?=( \pL+\b)?)~u

lookahead 允许在每个单词的开头遍历字符串(甚至在字符串的末尾,因为(?=( \pL+\b)?) 是一个始终正确的断言。)因为它不消耗任何字符。

很简单:

  • 布尔变量在开头设置为false。
  • 当布尔值为假且dict键中存在$m[0].$m[1]小写时,将布尔值设置为true并返回dict值,否则返回$m[0]
  • 当布尔值为真时,将其设置为false并返回一个空字符串

优点:您不必关心字典的大小。使用相同的想法,您甚至可以将算法扩展到更多单词而几乎没有更改,或者处理其中项目键具有不同单词数的 dict。

建议:当你想改变回溯限制或建立一个巨大的交替时,不要这样做。这只意味着你的方法不是好的。

【讨论】:

  • 您的模板不适合我。或者我不能正确你的建议。我可以通过使用我的字典和文本在我的函数中使用您的模板更新您的答案来向您展示吗? @Casimir et Hippolyte
猜你喜欢
  • 2022-08-24
  • 1970-01-01
  • 1970-01-01
  • 2012-06-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-13
相关资源
最近更新 更多