如何分阶段替换单词以获得所需的结果?

时间:2017-10-26 15:46:54

标签: php regex text preg-replace case-insensitive

您好。我只是无法得到我想要的结果。所以我将问题分成几部分来解决。如果有人会决定。如果一般 这个有可能。我有文字和三个数组。有必要分三个阶段来解决问题。

示例:

$array_for_step1 = array // Array for 1-st step
(
    "ewery day"     => "every day",
    "to school"       => "to univer",
);

$array_for_step2 = array // Array for 2-nd step
(
    'I',
    'go',
    'metro',
);

$array_for_step3 = array // Array for last 3-rd step
(
    "my"   => "he",
    "metro"  => "bus",
);

输入文字:

$input = "Ewery day I go To SchooL with metro. My friend too go to school but without metro.";

对决策阶段的评论:

第1步:

在这里,您需要使用文本中的值替换数组的键。使用数组$array_for_step1替换第一步后输入文本表单:

突出显示粗体 - 文字中的更改词语。

每天我使用metro去 To UniveR 。我的朋友也去了 To UniveR 但没有地铁。

第2步:

突出显示的粗体 - 下一步不需要替换的单词

在这里,您需要从数组中查找单词并从文本中标出它们,以便它们不会被替换或不可用于第三步的替换。使用数组`$ array_for_step2`替换第二步后输入文本形式:

每天通过 metro 到UniveR。我的朋友也到UniveR但没有 metro

第3步:

在这里,您需要使用文本中的值替换数组的键。使用数组$array_for_step3替换第3步后输入文本表单:

突出显示的粗体 - 分配了那些没有改变的词。

每天我都会带着地铁前往UniveR。 我的朋友也去了UniveR,但没有 metro

最终结果:

"Every day I go To UniveR with metro. My friend too go To UniveR but without metro."

我的示例函数用于替换数组键以对任何字符串情况进行赋值:

function ReplKeyToValue($request, $dictionary) // $request = string && $dictionary associative array
{
    $request = str_replace($search, $replace, $request); // replace special letters to default cyrillic letters

    $result = preg_replace_callback("/\pL+/u", function ($m) use ($dictionary) {
    $word = mb_strtolower($m[0]);
    if (isset($dictionary[$word])) {
        $repl = $dictionary[$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 $result;
}

我用英语给出了一个文本和数组值的例子。但这样你就可以轻松地决定和理解。但我需要你的解决方案适用于西里尔语文本和数组。

1 个答案:

答案 0 :(得分:-1)

我正在使用Perl语言粘贴代码以供您参考此任务。

use strict;

my $text = "Ewery day I go To SchooL with metro. My friend too go to school but without metro.";

#Applying Regex Search and Replace for the 1st hash.
my %hash1 = (

        "ewery day" => "every day",
        "to school" => "to univer",
    );

for my $key_hash1(keys %hash1){

    if($text =~ m/\Q$key_hash1\E/ig){
        $text =~ s/$key_hash1/$hash1{$key_hash1}/ig;
    }
}

print "Result after 1st task:".$text."\n";

#2nd and 3rd Task

my @array2 = ('I','go','metro');

my %hash2 = (

        "my" => "he",
        "metro" => "bus",
    );

for my $key_hash2(keys %hash2){

    if ( grep(/^\Q$key_hash2\E$/, @array2 ) ) {
       #print "$key_hash2 already present in the exceptional array\n";
        next;
    }
    else{
        #print "Replace in text $key_hash2 with $hash2{$key_hash2}\n";
        $text =~ s/$key_hash2/$hash2{$key_hash2}/ig;
    }
}
print "Result after 2nd task:".$text."\n";

您可以在以下网址中使用它 - Code Link