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

Php 使用preg_split获取字符串中两个标记之间的术语,php,regex,Php,Regex,好的,我有两条线 (我将其用于语言库系统,以允许翻译人员提供带有占位符的翻译) 在第一个字符串中,有两个实例。请注意,它并不总是一个实例,在某些情况下,它将是无实例、一实例、两实例或多实例 这是一个{[John Doe]}这是{[Jane Doe]} 然后我有一个字符串存储如下: C'est{[1]}和C'est{[2]} (翻译) 这是一个{[1]},这是一个{[2]} 因此,我需要做的是取第一个字符串,替换起始字符串{[]}之间的所有内容,并匹配每个实例,即第一个字符串的第一个字符串与第二个

好的,我有两条线

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

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

这是一个{[John Doe]}这是{[Jane Doe]}

然后我有一个字符串存储如下:

C'est{[1]}和C'est{[2]}

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

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

所以问题是。我该怎么做?我想先拆分,然后用第二个字符串匹配每个字符串的索引+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;

}

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

您就快到了。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,您现在可以肯定地知道,您将在奇数索引中找到标记的零件。

您就快到了。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,您现在可以确定将在奇数索引中找到标记的部分。

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

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

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

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]}{[2]}等依次替换{[]}中的每个项。我正在获得匹配项,所以这是一个开始。。但是我想知道是否有一个更简单的方法来做到这一点(也许通过你的preg\u replace\u回调只是一个不同的工作流?)好吧,我终于得到了!谢谢NikiC你的方法是正确的。看看我是怎么做到的,虽然在我编辑的帖子上面。好的,这是非常接近我需要的,但仍然需要一些调整。。问题是。。我需要用占位符{[1]}{[2]}等依次替换{[]}中的每个项。我正在获得匹配项,所以这是一个开始。。但是我想知道是否有一个更简单的方法来做到这一点(也许通过你的preg\u replace\u回调只是一个不同的工作流?)好吧,我终于得到了!谢谢NikiC你的方法是正确的。看看我在上面编辑的帖子里是怎么做的。它返回了所有的片段,而不仅仅是关键标签中的片段。很高兴了解你,不过,谢谢:)仍然习惯正则表达式..这返回了所有的片段,而不仅仅是密钥标签中的片段。很高兴了解你,不过,谢谢:)仍然习惯正则表达式。。