2009-10-21 1 views
2

나는 단어로 텍스트를 분할하려합니다.분할 텍스트, 복잡한 문제

예. "이걸 봐. 내 점수는 3.14이고, 나는 그것에 만족한다."라는 텍스트가 있다면. 이제 배열은 내 경우에는 발생하지 않아야

[0]=>Look, 
[1]=>at, 
[2]=>this, 
[3]=>My, 
[4]=>score, 
[5]=>is, 
[6]=>3, 
[7]=>14, 
[8]=>and, .... 
다음도 3.14 3에 나누어

14입니다. 두 개의 문자열을 나누어야하지만 두 개의 숫자를 나누지는 않습니다. 그것은 같아야합니다

[0]=>Look, 
[1]=>at, 
[2]=>this, 
[3]=>My, 
[4]=>score, 
[5]=>is, 
[6]=>3.14, 
[7]=>and, .... 

하지만 방법이 경우를 방지 할 수있는 아무 생각이 없습니다!

아무 생각없이이 문제를 해결하는 방법?

고맙습니다, 화강암

+0

이 질문이 도움이됩니까?http://stackoverflow.com/questions/790596/split-a-text-into-single-words –

+1

은 마침표가 아닙니다. " 구분 기호 배열에 두 번째로 있습니까? – avguchenko

답변

9

또는 사용 정규식 :

<?php 
$str = "Look at this.My score is 3.14, and I am happy about it."; 

// alternative to handle Marko's example (updated) 
// /([\s_;?!\/\(\)\[\]{}<>\r\n"]|\.$|(?<=\D)[:,.\-]|[:,.\-](?=\D))/ 

var_dump(preg_split('/([\s\-_,:;?!\/\(\)\[\]{}<>\r\n"]|(?<!\d)\.(?!\d))/', 
        $str, null, PREG_SPLIT_NO_EMPTY)); 

array(13) { 
    [0]=> 
    string(4) "Look" 
    [1]=> 
    string(2) "at" 
    [2]=> 
    string(4) "this" 
    [3]=> 
    string(2) "My" 
    [4]=> 
    string(5) "score" 
    [5]=> 
    string(2) "is" 
    [6]=> 
    string(4) "3.14" 
    [7]=> 
    string(3) "and" 
    [8]=> 
    string(1) "I" 
    [9]=> 
    string(2) "am" 
    [10]=> 
    string(5) "happy" 
    [11]=> 
    string(5) "about" 
    [12]=> 
    string(2) "it" 
} 
+0

약 3,14 및 3/14는? 분할됩니다. – Granit

+0

댓글을 달았습니다./([\ s _;?! \/\ (\) \ [\] {} <> \ r \ n "] | \. $ | [:,. \ -] 정말 대단히 감사합니다. – Granit

+0

저는 실제로 조금 엉망이되었습니다. 빨리 편집하겠습니다. – ptomli

6

strtok를 살펴 보자. 구문 분석 토큰을 ​​동적으로 변경할 수 있으므로 while 루프에서 문자열을 수동으로 분리하고 각 단어를 배열로 밀어 넣을 수 있습니다.

+0

제프 감사합니다. 나는 거의 해결책을 얻었지만 약간의 문제가있다. 구분 기호 목록이 있으며 구분 기호가 정확히 일치하는지 알 수 없습니다. 왜냐하면 두 개의 연속적인 토큰을 숫자로 볼 수 있기 때문에 그 숫자에 합류 할 수 있지만 그 중간에 무엇이 있었는지 알아야하기 때문입니다. – Granit

+0

+1 .. strtok()를 가장 신뢰할 수있는 내기라고 부르는 것이 싫지만 그의 경우에는 적용됩니다. –

+0

Granit : 내가 알고있는 것은 아닙니다. –

0

".", 대신 ". ",$delimiterList에 사용하십시오.

+0

당신은 그것에 대해 확신 할 수 없습니다. 나는 this.is.a.text와 같은 것을 처리 할 수 ​​있어야한다. – Granit

+0

언제 "this.is.a.text"가 있고 귀하의 질문에 언급 된대로 그것을 나누고 싶지 않아 ??? – powtac

1

내 첫번째 생각은 preg_match_all('/\w+/', $string, $matches);했지만 그건 당신이 가지고있는 것과 비슷한 결과를 제공합니다. 문제는 점으로 구분 된 숫자가 매우 모호하다는 것입니다. 소수점과 문장의 끝을 의미 할 수 있으므로 이중의 의미를 없애기 위해 문자열을 변경하는 방법이 필요합니다.

예를 들어 "Look at this.My score is 3.14, and I am happy about it. It's not 334,3 and today's not 2009-12-12 11:12:13."과 같이 여러 단어로 구성 할 수 있습니다.

우리는 분할 얻을하지 않을 무언가에 예외 인코딩 사전을 대체>를 통해 검색을 구축하여 시작합니다

$encode = array(
    '/(\d+?)\.(\d+?)/' => '\\1DOT\\2', 
    '/(\d+?),(\d+?)/' => '\\1COMMA\\2', 
    '/(\d+?)-(\d+?)-(\d+?) (\d+?):(\d+?):(\d+?)/' => '\\1DASH\\2DASH\\3SPACE\\4COLON\\5COLON\\6' 
); 

다음, 우리는 예외를 인코딩 :

foreach ($encode as $regex => $repl) { 
    $string = preg_replace($regex, $repl, $string); 
} 

하게 분할을 문자열 :

preg_match_all('/\w+/', $string, $matches); 

인코딩 된 단어를 다시 변환하십시오.

$decode = array(
    'search' => array('DOT', 'COMMA', 'DASH', 'SPACE', 'COLON'), 
    'replace' => array('.', ',',  '-', ' ',  ':' ) 
); 
foreach ($matches as $k => $v) { 
    $matches[$k] = str_replace($decode['search'], $decode['replace'], $v); 
} 

$matches에는 올바른 문장이있는 단어로 분리 된 원본 문장이 들어 있습니다.

예외로 사용되는 정규식을 원하는대로 간단하게 만들 수도 있지만 복잡 할 수도 있습니다. 예를 들어 첫 번째 단 둘이 끝나는 두 개의 전송과 숫자로 시작하는 다음 전송과 같은 모호성이 항상 있습니다. Number of the counting shall be 3.3 only and nothing but the 3.5 is right out..