Php 如何在$patterns和$replacements数组中使用具有大量(1000000)值的函数preg_replace?

Php 如何在$patterns和$replacements数组中使用具有大量(1000000)值的函数preg_replace?,php,arrays,replace,preg-replace,large-data,Php,Arrays,Replace,Preg Replace,Large Data,您好,亲爱的程序员们我在函数preg\u replace()的速度方面遇到了问题 当我在$patterns和$replacements数组中有很少的值(words)时,问题不在于从数组中搜索和替换文本的速度,当数组中的值数增加1.000.000时,函数preg_replace()被反复减慢。如果数组中的值(单词)超过1000000,如何在文本中搜索和替换?如何尽快更换?问题的解决方案是否可以缓冲或缓存?有什么建议,如何正确地对我采取行动 以下是我的阵列示例: $patterns = array

您好,亲爱的程序员们我在函数
preg\u replace()
的速度方面遇到了问题

当我在
$patterns
$replacements
数组中有很少的值(words)时,问题不在于从数组中搜索和替换文本速度,当数组中的值数增加1.000.000时,函数
preg_replace()
被反复减慢。如果数组中的值(单词)超过1000000,如何在文本中搜索和替换?如何尽快更换?问题的解决方案是否可以缓冲缓存?有什么建议,如何正确地对我采取行动

以下是我的阵列示例:

$patterns = 
array
(
0 => "/\bмувосокори\b/u",
1 => "/\bмунаггас\b/u",
2 => "/\bмангит\b/u",
3 => "/\bмангития\b/u",
4 => "/\bмунфачир\b/u",
5 => "/\bмунфачира\b/u",
6 => "/\bманфиатпарасти\b/u",
7 => "/\bманфиатчу\b/u",
8 => "/\bманфиатчуи\b/u",
9 => "/\bманфиатхох\b/u",
10 => "/\bманфи\b/u",
...........................
1000000 => "/\bмусби\b/u"
)

$replacements =
array
(  
0 => "мувосокорӣ",
1 => "мунағғас",
2 => "манғит",
3 => "манғития",
4 => "мунфаҷир",
5 => "мунфаҷира",
6 => "манфиатпарастӣ",
7 => "манфиатҷӯ",
8 => "манфиатҷӯӣ",
9 => "манфиатхоҳ",
10 => "манфӣ",
.....................
1000000 => "мусбӣ"
);

$text = "мувосокори мунаггас мангит мангития мунфачир манфиатпарасти...";
$result = preg_replace($patterns, $replacements, $text);
我在index.html文件中使用此javascript函数:


功能反应(str){
如果(str.length==0){
document.getElementById(“文本”).innerHTML=“”;
返回;
}否则{
var xmlhttp=new XMLHttpRequest();
xmlhttp.onreadystatechange=函数(){
if(this.readyState==4&&this.status==200){
document.getElementById(“text”).innerHTML=this.responseText;
}
};
open(“GET”、“response.php?request=“+str,true”);
xmlhttp.send();
}
}
PHP文件response.PHP源代码:


算法的时间复杂度大约为O(nm),其中n是替换数组中的字数,m是请求中的字数

由于所有模式似乎都在查找单词(
\b
前后),并且不使用任何其他正则表达式语法(仅限文字字符),因此通过将请求拆分为单词并在关联数组中查找它们,您将获得更好的性能,而根本不需要使用正则表达式

因此,将图案/替换数据定义为关联数组,如下所示:

$dict = array(
    "мувосокори" => "мувосокорӣ",
    "мунаггас" => "мунағғас",
    "мангит" => "манғит",
    "мангития" => "манғития",
    "мунфачир" => "мунфаҷир",
    "мунфачира" => "мунфаҷира",
    "манфиатпарасти" => "манфиатпарастӣ",
    "манфиатчу" => "манфиатҷӯ",
    "манфиатчуи" => "манфиатҷӯӣ",
    "манфиатхох" => "манфиатхоҳ",
    "манфи" => "манфӣ",
    ...........................
    "мусби" => "мусбӣ"
);
然后使用
preg\u replace\u callback
查找请求中的每个单词,并在上述词典中查找:

$response = preg_replace_callback("/\pL+/u", function ($m) use ($dict) {
    return isset($dict[$m[0]]) ? $dict[$m[0]] : $m[0];
}, $request);
时间复杂度将与请求中的字数成线性关系

处理大写/小写字母 如果您还需要匹配单词大写的任何变化,那么在字典中存储任何此类变化都会太多。相反,您可以使用所有小写字母保存字典,然后使用下面的代码。当与词典匹配时,它会检查原始单词的大写字母,并将其应用于替换单词:

$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);

当然,您不应该在代码中包含此转换,只需运行一次即可生成新的数组结构,然后将该数组文本放入代码中。

算法的时间复杂度大致为O(nm),其中n是替换数组中的字数,m是请求中的字数

由于所有模式似乎都在查找单词(
\b
前后),并且不使用任何其他正则表达式语法(仅限文字字符),因此通过将请求拆分为单词并在关联数组中查找它们,您将获得更好的性能,而根本不需要使用正则表达式

因此,将图案/替换数据定义为关联数组,如下所示:

$dict = array(
    "мувосокори" => "мувосокорӣ",
    "мунаггас" => "мунағғас",
    "мангит" => "манғит",
    "мангития" => "манғития",
    "мунфачир" => "мунфаҷир",
    "мунфачира" => "мунфаҷира",
    "манфиатпарасти" => "манфиатпарастӣ",
    "манфиатчу" => "манфиатҷӯ",
    "манфиатчуи" => "манфиатҷӯӣ",
    "манфиатхох" => "манфиатхоҳ",
    "манфи" => "манфӣ",
    ...........................
    "мусби" => "мусбӣ"
);
然后使用
preg\u replace\u callback
查找请求中的每个单词,并在上述词典中查找:

$response = preg_replace_callback("/\pL+/u", function ($m) use ($dict) {
    return isset($dict[$m[0]]) ? $dict[$m[0]] : $m[0];
}, $request);
时间复杂度将与请求中的字数成线性关系

处理大写/小写字母 如果您还需要匹配单词大写的任何变化,那么在字典中存储任何此类变化都会太多。相反,您可以使用所有小写字母保存字典,然后使用下面的代码。当与词典匹配时,它会检查原始单词的大写字母,并将其应用于替换单词:

$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);

当然,您不应该在代码中包含此转换,只需运行一次即可生成新的数组结构,然后将该数组文本放入代码中。

不清楚您的问题会使转换速度减慢多少。它是减慢了100万倍(预计会多做100万件事情),还是减慢了更多?这是一个性能改进问题,对吗不是破译的代码。我使用了一个javascript函数,它使用GET方法将textarea值传递给一个php文件,该文件可以立即更正单词。问题是,当数组中有更多替换值时,函数preg_replace的速度会减慢一点。因此,您需要以某种方式提高函数preg_replace的速度。例如,当我在HTML页面的文本区域中输入字母“a”时,javascript使用GET方法立即将该字母提取到php变量中,并使用函数preg_replace进行处理,然后返回。我也不知道函数的性能有多慢,但我只是没有对其进行测量。只是无法测量每一个输入何时被传递文本字段中的所有信息并被处理和返回。这是一个提高性能的问题,对吧。不清楚它从你的问题中减慢了多少。它是减慢了100万倍(预计会多做100万件事情),还是减慢了更多?这是一个性能改进问题,对吗不是破译的代码。我使用了一个javascript函数,它使用GET方法将textarea值传递给一个php文件,该文件可以立即更正单词。问题是,当数组中有更多替换值时,func