if ( array_key_exists($k,$checkboxes) && $v!= "")
${$k} = $v == 'on' ;
Проверяем, не пустое ли поле со словоформой. Если пустое, то специальную переменную переводим в true. При этом отрезаются возможные пробелы во введенной поисковой строке (функция trim), специальные символы заменяются на html-сущности (функция htmlspecialchars) и удаляются возможные html - и php-теги:
if ( $k == "wf" )
{
$WF= trim(htmlspecialchars(strip_tags($v))) ;
if($WF == "")
$query_is_empty = true;
}
При обработке полученной информации возможен вариант, когда пользователь не ввел новое слово для поиска, а переходит на следующую страницу вывода контекстов, тогда передается номер необходимой страницы, который запоминается в переменной $page:
if($k == 'page')
$page = trim(strip_tags($v));
Для перехода на новую страницу также надо получить позицию в массиве контекстов, с которой будет на этой странице начинаться вывод:
if($k == 'start')
$RStart = trim(strip_tags($_GET['start']));
Обработка варианта, когда пользователь только вошел на страницу поиска – поле словоформы должно быть пустое:
if($WF == "wf")
$WF_initial = "";
else
$WF_initial = $WF;
Если в поисковой строке присутствуют пробелы, это автоматически будет означать (независимо от того, была ли выбрана опция «Искать и в составных словоформах»), что части, разделенные пробелами, будут рассматриваться как части одной сложной словоформы. Таким образом, все пробелы заменяются на символ «_» (разделитель для частей составной словоформы):
$WF_copy = $WF;
$WF_copy = preg_match("/\s/",$WF_copy) ? preg_replace("/\s+/", "_+", $WF_copy) : $WF_copy ;
После обработки полученного от пользователя запроса необходимо создать шаблон для осуществления поиска. Во-первых надо проверить, осуществлялся ли поиск данной словоформы ранее. Вызывается функция check_previous_results, которая просматривает каталог searchResults с сохраненными ответами и ищет совпадение имени файла и данной словоформы + специальный индекс, получаемый из функции file_indexes, вызывающейся из check_previous_res. Индекс складывается из двух цифр, каждая из которых может быть либо 0, либо 1 в зависимости от того, был ли выставлен каждый из флагов в «on» для данного запроса:
if($path_to_file = check_previous_results(searchResults,
$WF_copy, $checkboxes))
$searchedFor_previously = true
Если пользователь не запрашивал конкретную страницу, а только отправил запрос, который до этого никто не вводил, то начинается формирование ответа. Создаются переменные для подсчета частотности нахождения словоформы в каждом разделе (драма, публицистика и т. д.) и подокументной частотности:
$found_1 = 0;
$found_2 = 0;
$found_3 = 0;
$found_4 = 0;
$found = 0;
$found_in_file = false;
Строка со словоформой разбивается по пробелам (если введено более трех слов, то появляется предупреждение о невозможности работы программы с этим количеством слов):
$w = split(" ", $WF);
if(count($w) > 3)
$to_much_words = true;
Поисковая строка обрабатывается в соответствии с правилом (в функции checkLetter): если введена словоформа с заглавной буквы, то в таком виде она и будет искаться, если же со строчной, – будет осуществляться поиск и с заглавной и со строчной буквы:
$WF = checkLetter($WF);
3.2.3 Создание шаблонов поискаПостепенно создается шаблон для поиска словоформы. Во-первых всем буквам «е» добавляется как вариант «ё», если при запросе была выбрана дополнительная опция «'Е' и 'Ё’ эквивалентны». При этом выражение «?:» (группировка без захвата) имеет следующее значение. Любой блок, обрамленный в регулярном выражении скобками, выделяется как единое целое и записывается в так называемый «карман». Содержимое таких карманов автоматически помещается в специальный массив, обратившись к которому можно получить отдельные части найденного цельного совпадения со всем шаблоном, ради которых обычно и ведется вся работа. Если же скобки используются не для создания кармана, например, а просто для удобства, то необходимо после открывающей скобки поставить «?:»:
$pattern = isset($yo) ? preg_replace('/(?:е|ё)/i','(?:е|ё)',$WF)
:$WF ;
Если пользователь сам поставил необходимые ударения, то они сохраняются (специальные символы экранируются), иначе после каждой гласной добавляется возможное ударение. Выражение «\\\\$0» обозначает следующее. В языке PHP удвоенный слэш в строках обозначает один слэш. Таким образом строка «\\\\$0» ($0 - ссылка на весь найденный шаблон $stressPattern) воспринимается PHP как строка «\\$0». Язык же регулярных выражений, в свою очередь, удвоенный обратный слэш интерпретируется как строка «\». Так как используемые обозначения для ударения («^» и «+») совпадают со значимыми для регулярных выражений символами, их необходимо в шаблоне экранировать обратным слэшом:
$pattern = preg_match("/$stressPattern/",$pattern) ?
preg_replace("/$stressPattern/", "\\\\$0", $pattern):
preg_replace(vowelsClass, "$0(?:$stressPattern)?", $pattern);
Если был выставлен флаг поиска в сложных словоформах, то в шаблон добавляется еще и вариант словоформы, в которой все пробелы заменены на «_» (знак, которым разделяются части сложной словоформы). При этом возможны ситуации, (предусмотренные шаблоном «_+»), когда используется знак «__» (двойной символ «_»). Этим знаком обозначается «разрывная» составная словоформа (например, «в__лице+»):
if(isset($compounds))
{
$pattern1 = preg_match("/\s/",$pattern) ? preg_replace("/\s+/",
"_+", $pattern) : $pattern ;
$pattern = "(?:".$pattern."|".$pattern1.")";
}
Создаем переменную для хранения выражения, определяющего возможные границы слов. Таковыми могут быть, помимо прочих: начало строки ($), конец строки (^), «\s» (символ пробела) , «\t» (символ табуляции), «\n» (символ перевода строки) и «\r» (символ возврата каретки):
$boundary = isset($compounds )? "(?:-|_|
|$|^|,|\.|:|;|!|\?|\r|\n|\t|\(|\)|\'|\")" :
"(?:\s|,|$|^|\.|:|;|!|\?|\r|\n|\t|\(|\)|\'|\")" ;
В итоге создается шаблон, в который на последнем шаге добавляются с обеих сторон от словоформы возможные разделители слов (ищутся не части слов, а отдельные слова):
$bPattern = "/$boundary$pattern$boundary/";
3.2.4 Просмотр текстов и сохранение результатов поискаДалее начинается непосредственная обработка текстов корпуса. Перебирая подряд все жанры и файлы корпуса (с помощью функции getFiles), считывается содержимое этих файлов, и последующие операции выполняются для каждой полученной строки, если она не пустая:
foreach ($genres as $v)
{
foreach (getFiles(corpus. strtoupper($v[path])) as
$filename)
{
$file = file($filename) ;
foreach ( $file as $lineNo=>$line )
{
$line = strip_tags(trim($line) );
if ( $line == '' ) { continue ; }
Сохраняется строка с заглавием документа. Ищется первая строка документа, и из нее удаляются скобки (тексты корпуса отформатированы с так, что заглавие заключено в квадратные скобки) «[» и «]»:
if($lineNo=0)
$header = preg_replace('/(?:\[|\])/','',$line);
Если в текущей строке было найдено совпадение с шаблоном, то увеличивается счетчик вхождений словоформы в текущем жанре и переменная – индикатор файлов с данной словоформой – выставляется в true:
if ( preg_match($bPattern,$line))
{
$tmp = 'found_'.$number;
$found_in_file = true;
$$tmp++;
С помощью функции glowLine в строке выделяется особым цветом найденная словоформа:
$collectedLine = glowLine($line,$nonBracket,$inBrackets,$pattern) ;
Для вывода контекста найденной словоформы необходимо получить предыдущие и последующие две строки (всего пять). При этом в этих дополнительных строках также проверяются и выделяются цветом glowLine дополнительные вхождения словоформы:
for ( $l=$lineNo-1, $count=0; ($count<_LIMIT_)
and ($l>$headerLines); --$l )
{
if ( trim($file[$l]) == '' )
{
$collectedLine = delimiterParagraph.
$collectedLine ;
} else
{
$collectedLine = glowLine($file[$l],$nonBracket,
$inBrackets,$pattern) . '<br>' .
$collectedLine ;
++$count
}
for ( $l=$lineNo+1, $count=0; ($count<_LIMIT_)
and ($l<count($file)); ++$l )
{
if ( trim($file[$l]) == '' )
{
$collectedLine.= delimiterParagraph ;
} else
{
if($count == 0) $collectedLine.= "<br>";
glowLine($file[$l],$nonBracket,$inBrackets,
$pattern,$ur).'<br>';
$collectedLine.= glowLine($file[$l],$nonBracket,
$inBrackets,$pattern).'<br>';
++$count ;
}
Добавляются многоточия в начале и в конце абзаца контекста.
В специальный массив записываются все полученные результаты поиска для последующего вывода пользователю. При этом строка с именем автора получается из строки заглавия (имя автора отделено от остальной части точкой):
$collectedLine = "...".$collectedLine."...";
array_push( $res, array ( genre=>$v[title], lineNo=>$lineNo,
line=>$collectedLine, textName=>$ar[4],
header=>$header,
author=>preg_replace('/\..*$/','',$header))
) ;
Если в данном файле было найдено вхождение искомой словоформы, то переменная для подокументной частотности увеличивается на единицу:
if($found_in_file)
$found++;
Теперь надо записать файлы в папке searchResults, сохраняющие полученный ответ. Перебираем записи в массиве результатов $res, предварительно создав папку для этого ответа:
if($i == 1) mkdir(searchResults.$WF_copy."+".file_indexes($checkboxes),
0777);
Добавляем к строке со словоформой индекс, созданный функцией file_indexes и создаем текстовый файл с полученным именем:
|
Из за большого объема этот материал размещен на нескольких страницах:
1 2 3 4 5 |


