2012-04-20 2 views
1

Цель: поиск по множеству десятков тысяч китайских предложений для определения предложений, содержащих исключительно символы из массива «известных символов».Поиск китайского текстового корпуса для предложений, содержащих только определенные символы

Например: Скажем, мой корпус состоит из следующих предложений: 1) 我 去 中国 2) 妳 爱 他 3) 你 在 哪里 Я только "знать" или хотят предложения, которые исключительно содержат эти символы..? : 1) 我 2) 中 3) 国 4) 你 5) 在 6) 去 7) 爱 8) 哪 9) 里. Первое предложение будет возвращено как результат, потому что все три его символа находятся в моем втором массиве. Второе предложение будет отклонено, потому что я не просил 妳 или 他. В результате будет возвращено третье предложение. Знаки препинания игнорируются (а также любые буквенно-цифровые символы).

У меня есть рабочий скрипт, который делает это (ниже). Мне интересно, эффективен ли это или нет. Если вы заинтересованы, пожалуйста, взгляните и предложите изменения, напишите сами или дайте совет. Я почерпнул некоторые из this script и проверил некоторые вопросы о stackoverflow, но они не рассматривали этот сценарий.

<?php 
$known_characters = parse_file("FILENAME") // retrieves target characters 
$sentences = parse_csv("FILENAME"); // retrieves the text corpus 

$number_wanted = 30; // number of sentences to attempt to retrieve 

$found = array(); // stores results 
$number_found = 0; // number of results 
$character_known = false; // assume character is not known 
$sentence_known = true; // assume sentence matches target characters 

foreach ($sentences as $s) { 

    // retrieves an array of the sentence 
    $sentence_characters = mb_str_split($s->ttext); 

    foreach ($sentence_characters as $sc) { 
     // check to see if the character is alpha-numeric or punctuation 
     // if so, then ignore. 
     $pattern = '/[a-zA-Z0-9\s\x{3000}-\x{303F}\x{FF00}-\x{FF5A}]/u'; 
     if (!preg_match($pattern, $sc)) { 
      foreach ($known_characters as $kc) {; 
       if ($sc==$kc) { 
        // if character is known, move to next character 
        $character_known = true; 
        break; 
       } 
      } 
     } else { 
      // character is known if it is alpha-numeric or punctuation 
      $character_known = true; 
     } 
     if (!$character_known) { 
      // if character is unknown, move to next sentence 
      $sentence_known = false; 
      break; 
     } 
     $character_known = false; // reset for next iteration 
    } 
    if ($sentence_known) { 
     // if sentence is known, add it to results array 
     $found[] = $s->ttext; 
     $number_found = $number_found+1; 
    } 
    if ($number_found==$number_wanted) 
     break; // if required number of results are found, break 

    $sentence_known = true; // reset for next iteration 
} 
?> 

ответ

0

Мне кажется, это должно сделать это:

$pattern = '/[^a-zA-Z0-9\s\x{3000}-\x{303F}\x{FF00}-\x{FF5A}我中国你在去爱哪里]/u'; 
if (preg_match($pattern, $sentence) { 
    // the sentence contains characters besides a-zA-Z0-9, punctuation 
    // and the selected characters 
} else { 
    // the sentence contains only the allowed characters 
} 

Убедитесь, чтобы сохранить файл исходного кода в UTF-8.

+0

Ницца, я ценю простоту. Есть ли точка, в которой регулярное выражение становится слишком длинным? Например, если я ищу предложения, которые содержат только символы из набора из 2000 разных символов, не будет ли это толкать его? – tsroten

+0

Технически это должно работать нормально, вероятно, лучше, чем повторять цикл за 2000 символов. Вероятно, вы бы не захотели хранить литеральное регулярное выражение, но динамически наращивайте его. – deceze

+0

Удивительный, спасибо за ответ, он отлично работает. Я довольно новичок в регулярном выражении, поэтому я очень не осведомлен о том, на что он способен. – tsroten

 Смежные вопросы

  • Нет связанных вопросов^_^