使用preg_split在字符串中的两个标记之间获取术语

时间:2012-02-18 21:55:33

标签: php regex

好的我有两个字符串。

(我将其用于语言库系统,以允许翻译人员使用占位符提供翻译。)

在第一个字符串中,有两个实例。请注意,它并不总是单个实例,有些情况下它将是无,一个,两个或更多。

这是{[John Doe]},这是{[Jane Doe]}

然后我有一个像这样存储的字符串:

C'est {[1]} et c'est {[2]}

(翻译) 这是{[1]},这是{[2]}

所以我需要做的是取第一个字符串,替换起始字符串的{[]}之间的所有内容并匹配每个实例,即第一个字符串第一个字符串{[1]}等等。请记住我使用{[1]}和{[2]}的原因是因为在某些语言中,术语可能以不同的顺序出现以保证准确性,但仍然是不需要自我翻译的术语(名称)。

所以问题是。我该怎么做呢?我在想preg_split,然后将每个的index + 1与第二个字符串进行匹配。那部分我可以处理。我遇到的问题是正确的正则表达式搜索...

这是我能得到的尽可能接近..

preg_split('/[(\{\[).*(\]\})]/', $str, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);

返回{[和]}的每个实例之前和之后的所有内容的数组,当我只是想要获取两者之间的内容时..

编辑:来自NikiC答案的解决方案。

function lang($str){
    $nwStr = $str;
    preg_match_all('(\{\[(.+?)\]\})', $str, $placeholders);
    foreach ($placeholders[0] as $mk => $match) {
        $pos = $mk+1;
        $nwStr = str_replace("$match","{[$pos]}",$nwStr);
    }
    $result = preg_replace_callback('(\{\[(\d+)\]\})', function ($matches) use ($placeholders) {
        $n = $matches[1]-1;
        return $placeholders[1][$n];
    }, $translation);
    return $result;

}

基本上我在这里做的是首先循环以用占位符替换匹配,以便我可以在我的语言文件中匹配正确的占位符文本。 (即从输入字符串中创建正确的标签字符串)

2 个答案:

答案 0 :(得分:3)

首先从字符串中抓取占位符:

preg_match_all('(\{\[(.+?)\]\})', $string, $matches);
$placeholders = $matches[1];

现在替换为回调:

$result = preg_replace_callback('(\{\[(\d+)\]\})', function ($matches) use ($placeholders) {
    $n = $matches[1] + 1;
    return $placeholders[$n];
}, $translation);

答案 1 :(得分:1)

你快到了。 PREG_SPLIT_DELIM_CAPTURE捕获()之间的群组,因此:

preg_split('/(\{\[.*\]\})/U', $str, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);

应该更好。我还添加了U修饰符,以便*不合适。

编辑,您还有一对[],绝对不属于那里!

另一件事,你可能希望在{[...]}构造之间有部分,所以这样更好:

preg_split('/\{\[(.*)\]\}/U', $str, -1, PREG_SPLIT_DELIM_CAPTURE);

通过删除PREG_SPLIT_NO_EMPTY,您现在可以确定您将在奇数索引处找到标记的部分。