2015-11-20 23 views
0

我有两个数组音译内,者除外的所有字符映射花括号

$latin = ['dž', 'lj', 'nj', 
    'a', 'b', 'c', 'č', 'ć', 
    'd', 'đ', 'e', 'f', 'g', 
    'h', 'i', 'j', 'k', 'l', 
    'm', 'n', 'o', 'p', 'r', 
    's', 'š', 't', 'u', 'v', 
    'z', 'ž', 
    'DŽ', 'LJ', 'NJ', 'Dž', 'Lj', 'Nj', 
    'A', 'B', 'C', 'Č', 'Ć', 
    'D', 'Đ', 'E', 'F', 'G', 
    'H', 'I', 'J', 'K', 'L', 
    'M', 'N', 'O', 'P', 'R', 
    'S', 'Š', 'T', 'U', 'V', 
    'Z', 'Ž' 
]; 

$cyrillic = ['џ', 'љ', 'њ', 
    'a', 'б', 'ц', 'ч', 'ћ', 
    'д', 'ђ', 'e', 'ф', 'г', 
    'x', 'и', 'j', 'к', 'л', 
    'm', 'н', 'o', 'п', 'p', 
    'c', 'ш', 'т', 'y', 'b', 
    'з', 'ж', 
    'Џ', 'Љ', 'Њ', 'Џ', 'Љ', 'Њ', 
    'A', 'Б', 'Ц', 'Ч', 'Ћ', 
    'Д', 'Ђ', 'E', 'Ф', 'Г', 
    'X', 'И', 'J', 'K', 'Л', 
    'M', 'H', 'O', 'П', 'P', 
    'C', 'Ш', 'T', 'Y', 'B', 
    'З', 'Ж' 
]; 

所以,当我使用str_replace函数($拉丁,$西里尔,$字符串),它的伟大工程。 但字符串可以是这样的:

$string = 'Today is {day_name} and time is {time}'; 

是否有可能所有字符映射除了花括号内的人。

这是例子:

$string = 'Today is {day_name} and time is {time}'; 
echo str_replace($latin, $cyrillic, $string); 
+0

显示你的代码,你已经尝试请 –

+0

塞尔维亚音译 - 真好!我已经将我的转换器从西里尔文写入拉丁文,效果很好,但是从拉丁文到西里尔文都存在挑战,例如专有名称应该保留在原文中。 –

+1

@bub我在说明中添加了代码 – mariola23

回答

1

可以使用preg_split使用regex{}包围字符分割串 -

(\{[^}]*\}) 

,然后选择性地将字符串替换逻辑。
事情是这样的 -

$string = "sad {day_name} and time is {time}"; 

// Split by the regex 
$s_arr =preg_split(
    "/({[^}]*})/", 
    $string, 
    -1, 
    PREG_SPLIT_DELIM_CAPTURE 
); 

// The string is split such that only odd numbers 
// constitute the split value 
foreach($s_arr as $k=>&$m){ 
    if($k%2 === 0){ 
     $m = str_replace($latin, $cyrillic, $m); 
    } 
} 
unset($m); 

$resp_str = implode("", $s_arr); 
echo $resp_str; 

输出 -

caд {day_name} aнд тиme иc {time} 
+0

谢谢@Kamehameha!它效果很好。 – mariola23

+1

请注意,否定字符类'[^}] *'比惰性点匹配效率更高。您不需要在PHP正则表达式中转义'}'。 –

+0

@stribizhev awesome ...使用否定字符类后,从24步骤到12步步骤...谢谢:) – Kamehameha

2

使用

$arr = array_combine($latin, $cyrillic); 
$string = 'Today is {day_name} and time is {time}'; 

echo preg_replace_callback('/\{[^}]*}(*SKIP)(*F)|./', function ($m) use ($arr) { 
    return array_key_exists($m[0], $arr) ? $arr[$m[0]] : $m[0]; 
}, 
$string); 

IDEONE demo,结果是:Toдay иc {day_name} aнд тиme иc {time}。在这里,我将两个数组组合成1个带有键和值的数组,然后匹配任何字符而不是换行符(= key)(添加/s修饰符以匹配所有字符),并检查数组中是否存在该键。如果是,请更换。

正则表达式匹配:

  • \{[^}]*}(*SKIP)(*F) - 一个子开始{随后比}其他然后匹配闭合}和整个匹配的子0或多个字符被从匹配值省略由于动词(*SKIP)(*FAIL)
  • | - 或...
  • . - 任何字符,但换行符。

请参阅the regex demo on regex101.com

+0

谢谢@stribizhev!它效果很好。 – mariola23

+0

很高兴提供帮助。请考虑接受最适合您的解决方案(请参阅[如何接受所​​有答案](http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work))。请注意,通常会接受首先提供的正确答案。您也可以根据效率和其他因素进行选择。 –

+0

@stribizhev,我有一个问题......'\ {[^}] *}(* SKIP)(* F)'为什么在模式开始时有一个反斜杠? – vitozev