2012-02-12 8 views
1

에 나중에 재 삽입 문자열의 나머지 :임시 라벨/태그를 제거하고

인수를 위해서
$string = "string with between brackets and"; 

작업이 '예'라는 단어와 'B'로 시작하는 모든 단어를 연결할 수 있습니다.

"string with {LABELS} yesbetween yesbrackets {HERE} and {HERE}" 

내 질문은 : 나는이 작업을 수행 할 수있는 방법

function operate($string) { 
    $words = explode(' ', $string); 
    foreach ($words as $word) { 
    $output[] = (strpos($word, 0, 1) == 'b') ? "yes$word" : $word; 
    } 
    return implode(' ', $output); 
} 

이 함수의 출력은

"string with yesbetween yesbrackets and" 

가 지금은 제자리로 일시적으로 삭제 레이블을 삽입 할 것 ? 중요 : operations()를 변경할 수 없기 때문에, 솔루션은 operate() 또는 뭔가 주위에 래퍼 함수를 ​​포함해야합니다. 나는 이것을 꽤 오래 동안 생각해 왔지만 이것을하는 방법에 대해서는 혼란 스럽다. 너 좀 도와 줄 수있어?

편집 :이 게시물에는 실제 조작()을 넣는 것이 너무 많습니다. 그것은 정말로 가치를 추가하지 않을 것입니다. 여기에() 실제 출력과 실제 출력 사이에는 큰 차이가 없습니다. 여기에있는 아이디어를 실제 상황으로 번역 할 수 있습니다 .-)

+0

당신은 operate'이 구체적으로 무엇을 '설명 할 필요가 몇 줄의 코드 또는이 좋은 답변을 마련하기 어려울 것 . –

+0

실제로,()는 POS 태그를 붙인 태그로서, 먹이가 된 단어에 먼저 태그를 붙입니다 :/VB와/VB 사이의/NN과/IN 사이의 문자열/NN (태그는 짜증나게합니다. 이리). 그런 다음 단어의 일부를 고정 된 문자로 태그 지정합니다. 그 결과는 원칙적으로 OP에서의 operations()에서 설명한 것과 유사합니다. 연산을 수행하는 단어의 수는 입력 된 단어의 수와 동일하지만 일부 단어의 앞에는 '예'가 연결됩니다. 따라서 출력 된 단어에서 '예'를 제거하여 원래 입력을 찾을 수 있습니다. 이게 도움이 되길 바란다. – Pr0no

답변

2

이에 대한 대답은 거세한 숫양에 따라 달라집니다 여부를 당신은 당신이 그것을 바꿀 수없는 경우에도,operate()을 이해 할 수 있습니다.

당신이 operate()에 전혀 파악할 수없는 경우는, 문제는 간단하게 해결 할수 있습니다 : 당신이

  • 중 하나가 필요 라벨을 다시 삽입 자신의 오프셋 또는 '돈 경우 상대 위치 (당신은 그들을 알 수 없다 t (당신이 operate() 그들에 작동 방법을 모르는 경우는, 그것들을 가질 수 없습니다)) 자신의 위치에 대한
  • 마커를 operate()을 알고

당신이 operate()에 적어도 몇 가지 통찰력이있는 경우, 다음

  • operate() 경우 재 조립

    • operate($a . $b)==operate($a) . operate($b) 경우에, 당신은 단지 operate()을 통해 비 라벨 부분을 실행 레이블하여 원래의 입력을 분할하지만, 분명하지 레이블 :이 풀 수있는 쉬운 사이에 뭔가가된다 ("\ 0"및 친구들이 마음에 들었습니다) 혼자만의 자리 표시 자 문자열을 보장 할 수 있습니다. 그런 다음 레이블을 순서대로 추출하고 자리 표시 자로 바꾸고 결과를 실행합니다 operate() 이상을 통해 저장된 레이블로 자리 표시자를 바꿉니다 (순서대로)

    편집

    의견을 읽은 후, 여기

    $input = "string with {LABELS} between brackets {HERE} and {HERE}"; 
    
    //Extract labels and replace with \0 
    $tmp=preg_split('/(\{.*?\})/',$input,-1,PREG_SPLIT_DELIM_CAPTURE); 
    $labels=array(); 
    $txt=array(); 
    $islabel=false; 
    foreach ($tmp as $t) { 
        if ($islabel) $labels[]=$t; 
        else $txt[]=$t; 
        $islabel=!$islabel; 
    } 
    $txt=implode("\0",$txt); 
    
    //Run through operate() 
    $txt=operate($txt); 
    
    //Reasssemble 
    $txt=explode("\0",$txt); 
    $result=''; 
    foreach ($txt as $t) 
        $result.=$t.array_shift($labels); 
    
    echo $result; 
    
  • +0

    의견을 보내 주셔서 감사합니다. 첫 번째 의견에 대한 내 회신을보고 업데이트 된 운영()을 살펴보십시오. 이것이 필요한 통찰력을 제공합니까? – Pr0no

    +0

    AFAIKS는'\ 0'을 남기 때문에 원래 문자열에'\ 0'이 없다면 위의 두 번째 옵션이 작동합니다. –

    +0

    죄송합니다. \ 0은 무엇을 의미합니까? 입력 문자열에는 항상 zA-Z {}가 포함되며 대괄호 사이에 다른 문자 (예 : {bracket : 2344})가 포함되지만 어쨌든 먼저 필터링됩니다. – Pr0no

    1

    다음은 처음 시도 할 때의 방법입니다. 문자열을 하나의 단어로 나눈 다음, 단어가 'braced'인지 아닌지에 따라 하나씩 operations()로 공급하십시오.

    $input = "string with {LABELS} between brackets {HERE} and {HERE}"; 
    $inputArray = explode(' ',$input); 
    foreach($inputArray as $key => $value) { 
        if(!preg_match('/^{.*}$/',$value)) { 
        $inputArray[$key] = operate($value); 
        } 
    } 
    $output = implode(' ',$inputArray); 
    
    +0

    operations()는 POS 태그 지정자이므로 (첫 번째 회신 및 업데이트 된 작업()에 대한 내 의견을 참조) 작업을 수행하기 위해 전체 문자열 (레이블 없음)을 한 번에 입력해야합니다. 그것을 한 단어 씩 먹이로주는 것은 선택 사항이 아닙니다. – Pr0no