2013-07-18 2 views
0

대괄호로 된 태그 사이에 텍스트를 가져 오려고합니다.사용자 정의 문자열 태그에 복잡한 정규식

단순한 문자열의 예를 보자 :

[프랑스]이 프랑스 텍스트이다/프랑스] [영어] 이것은 PHP에서 다음 [/ 영어]

그리고 영어 텍스트입니다 (https://stackoverflow.com/a/9826656/962734 사용) :

private function translate($string) 
{ 
    $start = "[".$this->lang."]"; 
    $end = "[/".$this->lang."]"; 
    $string = " ".$string; 
    $ini = strpos($string,$start); 
    if ($ini == 0) return $string; 
    $ini += strlen($start); 
    $len = strpos($string,$end,$ini) - $ini; 
    return substr($string,$ini,$len); 
} 

더 복잡한 솔루션은 어떨까요?

언어가 설정되지 않은 경우 -> 기본값 (영어)을 사용합니다. 문자열에 태그 외부에 문자열이 포함되어 있으면 선택한 언어로 표시됩니다. . 문자열이 아닌 요청 언어가 포함 된 경우 -> 디스플레이 기본을 기본 설정되지 않은 경우 (또는, 디스플레이가 먼저 문자열에서 발견 예 : PHP를 사용하여 할 수있는 가장 좋은 방법은 무엇

$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 

내가 의심? 이 복잡한 정규식이 필요하다고 내가 정규식에 익숙하지 않은 해요로,하지만, 내가 다른 방법이 있는지 알고 싶습니다

편집 :. 제프 (https://stackoverflow.com/a/17727494/962734)에서 제공하는 답변에 따라

, 대부분의 경우 작동하는 함수를 만들었습니다. 감사.

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; 
} 
+0

텍스트의 유일하게 가능한 형식인가요? 그들은 항상 서로 옆에 있고 한 줄에 하나만있을 것입니까? – SmokeyPHP

+0

아닙니다. 이것들은 문자열이 어떻게 보일지에 대한 예일뿐입니다. –

답변

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

을이

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" 
    } 
} 

그래서 당신이 [2] 언어의 배열에 액세스 할 돌아갑니다 이름과 배열 [3] 실제 텍스트입니다. 이 특정 상황에

+0

나중의 작업을 위해 좋은 기초 자료로 받아 들일 수 있습니다. 내 질문을 업데이트하고 답변을 기반으로 대부분의 경우 작동 기능을 추가했습니다. 감사. –

0

이 시도 :

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]; 
     } 


} 
+0

이것은 기본 정적 솔루션입니다. regex없이 첫 번째 예제와 같은 방식으로 작동하므로 실제로는 복잡하지 않습니다. 감사. –

+0

왜 제대로 작동하는지 "복잡한"이유를 모르겠습니다. 당신이 설명하지 않은 것이 무엇을 더 필요합니까? – Drew

+0

문자열에 lang이 설정되어 있는지 확인하지 않습니다. 2. 문자열에 기본 언어가 설정되어 있는지 확인하지 않습니다. 그것은 태그 외부의 문자열을 받아들이지 않습니다 ... 특정 예제에 대한 "작업"솔루션보다 많은 경우에 작동하도록 보편적 인 솔루션을 갖고 싶습니다. 감사. –

1

:

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 
+0

예. 내 예제에서는 트릭을하기 때문에 Upvoted. 하지만 여전히 복잡한 솔루션은 아닙니다. 감사. –