Php 自定义字符串标记上的复杂正则表达式
我试图在方括号中的标记之间获取文本 让我们看看简单的字符串示例: 这是一篇法语文本这是一篇英语文本 然后在PHP中(使用): 更复杂的解决方案如何 我的意思是如果没有设置语言->使用默认值(英语)。如果字符串包含标签外的字符串,则沿所选语言显示该字符串。如果字符串不包含所请求的语言->显示默认值(或者如果未设置默认值,则在字符串中首先显示)。示例:Php 自定义字符串标记上的复杂正则表达式,php,regex,string,preg-match,Php,Regex,String,Preg Match,我试图在方括号中的标记之间获取文本 让我们看看简单的字符串示例: 这是一篇法语文本这是一篇英语文本 然后在PHP中(使用): 更复杂的解决方案如何 我的意思是如果没有设置语言->使用默认值(英语)。如果字符串包含标签外的字符串,则沿所选语言显示该字符串。如果字符串不包含所请求的语言->显示默认值(或者如果未设置默认值,则在字符串中首先显示)。示例: $this->language->__set("defLang", "english"); $str = "This is a [fr
$this->language->__set("defLang", "english");
$str = "This is a [french]French text[/french][english]English text[/english]";
$this->language->lang = "french";
return $this->language->translate($str);
//OUTPUT: This is a French text
$str = "This is a [deutch]Deutch text[/deutch][english]English text[/english]";
$this->language->lang = "french";
return $this->language->translate($str);
//OUTPUT: This is a English text
$str = "This is a [french]French text[/french][deutch]Deutch text[/deutch]";
$this->language->lang = "english";
return $this->language->translate($str);
//OUTPUT: This is a French text
使用PHP实现这一点的最佳方法是什么?我怀疑它需要复杂的正则表达式,但由于我不熟悉正则表达式,我想知道是否还有其他方法
编辑:
根据jeff()提供的答案,我制作了在大多数情况下都能工作的函数。谢谢
function translate($text)
{
$exp = '/(\[(.+?)\])(.+?)\[\/.+?\]/i';
$m = preg_match_all( $exp, $text, $matches);
if($m){
$mtchs = $matches[0];
$langs = $matches[2];
$texts = $matches[3];
$c = 0;
$foundLang = false;
$foundFirstOptionalLang = false;
foreach($langs as $l){
if($l == $this->lang){
$text = str_replace($mtchs[$c], $texts[$c], $text);
$foundLang = true;
}else{
if(!$foundFirstOptionalLang && $l == $this->defLang){
$optionalText = str_replace($mtchs[$c], $texts[$c], $text);
$foundFirstOptionalLang = true;
}
$text = str_replace($mtchs[$c], "", $text);
}
$c++;
}
if (!$foundLang) $text = $optionalText;
}
return $text;
}
试试这个:
function translate($str){
// If the language has been set use it, otherwise use the default value
$lang = isset($this->language->lang)?$this->language->lang:$this->language->defLang;
if(preg_match("/\[$lang\](.+)\[\/$lang\]/", $str, $m)){
return $m[1];
}else{
// There was no text found for $lang, fall back to english
preg_match("/\[english\](.+)\[\/english\]/", $str, $m);
return $m[1];
}
}
您可以使用以下内容:
$exp = '/(\[(.+?)\])(.+?)\[\/.+?\]/i';
$str = "This is a [french]French text[/french] and [english]English text[/english]";
$m = preg_match_all( $exp, $str, $matches);
echo "<pre>";
var_dump( $matches);
echo "</pre>";
因此,您可以访问数组[2]作为语言名称,访问数组[3]作为实际文本。对于这种特殊情况:
这是唯一可能的文本格式吗?它们是否总是彼此相邻,并且在字符串中只有一个集合?不太可能。这些只是字符串外观的示例。这是基本的静态解决方案。不太复杂,因为它的工作方式与我第一个没有正则表达式的示例相同。谢谢。不确定为什么要将其设置为“复杂”如果它有效。它还需要做什么你没有解释的事情呢?它不检查字符串中是否设置了任何lang。2.也不检查字符串中是否设置了默认语言。它不接受标记之外的字符串…不仅仅是“有效”一个特定例子的解决方案我希望有一个通用的解决方案,使它在大多数情况下都能工作。谢谢。是的。投票结果是因为对我的例子来说,它能起作用。但它仍然不是真正复杂的解决方案。谢谢。我可以接受这一点,因为它为以后的工作奠定了良好而清晰的基础。我更新了我的问题,在大多数情况下添加了工作函数,bas谢谢你的回答。
$exp = '/(\[(.+?)\])(.+?)\[\/.+?\]/i';
$str = "This is a [french]French text[/french] and [english]English text[/english]";
$m = preg_match_all( $exp, $str, $matches);
echo "<pre>";
var_dump( $matches);
echo "</pre>";
array(4) {
[0]=>
array(2) {
[0]=>string(28) "[french]French text[/french]"
[1]=>string(31) "[english]English text[/english]"
}
[1]=>
array(2) {
[0]=> string(8) "[french]"
[1]=> string(9) "[english]"
}
[2]=>
array(2) {
[0]=>string(6) "french"
[1]=>string(7) "english"
}
[3]=>
array(2) {
[0]=>string(11) "French text"
[1]=>string(12) "English text"
}
}
function getTextInTag($text,$tag='english')
{
$innerText = preg_replace('#^.*\['.$tag.'\](.+?)\[/'.$tag.'\].*$#','$1',$text);
if($innerText == $text) $innerText = preg_replace('#^.*\[english\](.+?)\[/english\].*$#','$1',$text);
$text = preg_replace('#(\[[^\]]+\].+?\[/[^\]]+\])+#','',$text);
return $text.$innerText;
}
getTextInTag('This is a [french]French text[/french][english]English text[/english]'); //This is a English text
getTextInTag('This is a [french]French text[/french][english]English text[/english]','french'); //This is a French text
getTextInTag('This is a [french]French text[/french][english]English text[/english]','spanish'); //This is a English text