Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
C++. Мастер-класс в задачах и примерах. Авторы: Кузнецов М.В., Симдянов И.В. PHP. Практика создания Web-сайтов (второе издание). Авторы: Кузнецов М.В., Симдянов И.В. MySQL на примерах. Авторы: Кузнецов М.В., Симдянов И.В. PHP Puzzles. Авторы: Кузнецов М.В., Симдянов И.В. Самоучитель MySQL 5. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум Регулярные Выражения

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: помогите с preg_match(найти в подмассивах совпадения)
 
 автор: Jenshina   (25.06.2010 в 15:15)   письмо автору
 
 

Здравствуйте, джентельмены! Помогите даме, пожалуйста, с такой задачей:
У меня есть файл с данными. Оттуда я их читаю в массив, а потом делю этот массив на подмассивы.
Еще есть переменные, в которые передаются или слова, или цифры, или вообще ничего, они в том же порядке, что и подмассивы.
Теперь сказали найти в подмассивах совпадения.


$peremen = array($a,$b,$c,$d,$e,$f,$j);
$result = count($peremen);
$file = "massiv.txt";
if (is_file($file)):
{
    $fp = fopen($file, "r") ;
  $file_array = file("massiv.txt"); // Считывание файла в массив $file_array-считывается
  

fclose($fp); 
}


 $podmassiv = array_chunk($file_array,$result);//делит на подмассив 

foreach ($podmassiv as $key => $value){
foreach ($value as $pers => $value)
if (preg_match.........................................


А как делать дальше?
Заранее благодарю.

  Ответить  
 
 автор: sim5   (25.06.2010 в 15:28)   письмо автору
 
   для: Jenshina   (25.06.2010 в 15:15)
 

Функции пересечения массивов смотрите.

PS. Правда, если значания первого массива, имеют такие же значения как и части массивов из файла. Иначе поможет strpos.
Вы бы лучше примеры значений массивов привели, вместо переменных, чтобы более понятно было чего сравнивать, сдается, что вполне можно обойтись без рег. выражений.

  Ответить  
 
 автор: Jenshina   (25.06.2010 в 16:19)   письмо автору
 
   для: sim5   (25.06.2010 в 15:28)
 

массив:
array [] = (васильчиков, вася, муж, 152, 29);
array [1]= (любина, люба, жен, 180, 80);

из формы поиска получаем 5 переменных.
например,
$a = "любина"
$b = "люба"
$c = "жен"
$d = "180"
$e = "80"
или, к примеру, несколько переменных могут вернуться пустыми, если кто-то решит искать "люба" и "80".
В первом случае поиск должен найти array [1]= (любина, люба, жен, 180, 80) и вывести, а во втором найти и вывести всех люб, которым 80. (с фамилией и всеми атрибутами)

  Ответить  
 
 автор: sim5   (25.06.2010 в 16:43)   письмо автору
 
   для: Jenshina   (25.06.2010 в 16:19)
 

А вы не задумывались хранить такие данные не в файле, а в базе? И искать будет легче, и не потребуется таких примудростей для поиска.

  Ответить  
 
 автор: Jenshina   (25.06.2010 в 16:51)   письмо автору
 
   для: sim5   (25.06.2010 в 16:43)
 

там условия такие были

  Ответить  
 
 автор: sim5   (25.06.2010 в 16:58)   письмо автору
 
   для: Jenshina   (25.06.2010 в 16:51)
 

Странно, такие данные так и просятся в таблицу.
Ну ладно, так значит так. Тогда повторяю - вам нужны функции персечения массивов. Если при сравнении будет возвращен массив совпадающих данных, то массив в котором происходит сравнение содержит искомые данные. Разберетесь?

PS. Вот этот момент:
$result = count($peremen);
.....
$podmassiv = array_chunk($file_array,$result);
не понятен. Зачем разбивать на такие куски массив из файла?

  Ответить  
 
 автор: Jenshina   (25.06.2010 в 17:13)   письмо автору
 
   для: sim5   (25.06.2010 в 16:58)
 

Потому что из пяти форм данные первоначально записываются в файл по одному элементу с концом строки.

И когда я из файла массив достаю так:
$fp = fopen($file, "r") ;
$file_array = file("massiv.txt");

получаются, что все данные идут подряд:
[0]=>васильчиков
[1]=.>вася
[2]]=>муж
[3]=>150
и тд
А мне же нужно искать пять переменных, в том же порядке, что они вносились в файл.
Поэтому я просто разбиваю массив на подмассивы по 5 элементов
array[0]
васильчиков
вася
муж
150
29
array[1]
любина
люба
жен
180
80

логически видится, что предматч как-то должен быть в цикле, но до конца не соображается.

Апдейт: смотрю функции пересечения сейчас, но что-то не пойму.
Если у меня несколько переменных будут пустыми, каким образом применять функцию?
В этом случае, наверное, поиск будет работать некорректно?

  Ответить  
 
 автор: sim5   (25.06.2010 в 18:06)   письмо автору
 
   для: Jenshina   (25.06.2010 в 17:13)
 

Если даже и хранить это в файле, то лучше в виде сериализованного массива.
Ну допустим пусть будет так, как есть, но для работы нужно будет полученные строки из файла преобразовать в массив, то есть получить многомерный массив. Вот именно такой и надо держать в файле. Разбивать что-то.... этого я так и не понял. Не понятен момент от каких пяти форм данные? У вас что каждый запрос (фамилие, имя, пол...), это разные формы? Если так, то это глупо.

Допустим, что у вас файл хранит данные о неких товарищах, особях муж/женск. пола, а в форме вы посылаете запрос на поиск среди этих товарищей нужного. К примеру, файл 'name.txt' содержит следующие данные (учитываю написание первых символов, и об этом надо помнить, для данного примера):
любина, люба, жен, 180, 80
колина, кира, жен, 160, 70
васильчиков, вася, муж, 152, 29
степанова, люба, жен, 160, 70

Далее делаем так:
<?
if($_POST) { //если пришел запрос на поиск
  //получаем список
  
$a file('name.txt');
  
//преобразуем его в многомерный массив
  
$m = array();  //многомерный массив $m будет содержать список наших особей
  
foreach($a as $varray_push($marray_map('trim'explode(',',$v)));
  
//вот что получаем - вот так данные лучше держать в файле
  
echo '<pre>'//это для контроля, можно удалить
  
print_r($m); //это для контроля, можно удалить
  //удаляем пробелы в элементах массива запроса на поиск
  
$_POST array_map('trim'$_POST);
  
//поиск
  
foreach($m as $key=>$val) {
    
//если пересечение возвращает один или несколько запрашиваемых данных
    //то выводим эти данные
    
if(array_intersect($val$_POST)) echo implode(' 'array_map('ucfirst'$val)) . '<br>';
    
//если нужен поиск именно по совпадению всех данных, 
    //а не по любым из них, то достаточно поставить такое уловие,
    //переписав строку сравнения массивов так:
    
if(array_intersect($val$_POST) && count($_POST)==count(array_intersect($val$_POST))) 
         echo 
implode(' 'array_map('ucfirst'$val)) . '<br>';  
    
//заметьте, что здесь первые символы элементов переведены в верхний регистр
  

}
?>
<form action="" method="post">
Фамилия: <input type="text" name="fm"><br>
Имя: <input type="text" name="nm"><br>
Пол: <input type="text" name="sx"><br>
Рост: <input type="text" name="wh"><br>
Возраст: <input type="text" name="ag"><br>
<input type="submit" value="Искать">
</form>

Это пример, но суть, о которой я говорил выше, в этом - массив (именно массив, а не строка разделенная запятыми) из списка, сравнивается с массивом полученным из формы.

PS. Если я прав по вопросу выше (о пяти разных формах), то вы уж опишите подробнее, что и как, что и с чем.... Сдается, что у вас лишнее на вашей кухне.

  Ответить  
 
 автор: Jenshina   (25.06.2010 в 19:27)   письмо автору
 
   для: sim5   (25.06.2010 в 18:06)
 

>Если даже и хранить это в файле, то лучше в виде сериализованного массива.

>Ну допустим пусть будет так, как есть, но для работы нужно будет полученные строки из файла преобразовать в массив, то есть получить многомерный массив. Вот именно такой и надо держать в файле.

>Разбивать что-то.... этого я так и не понял. Не понятен момент от каких пяти форм данные? У вас что каждый запрос (фамилие, имя, пол...), это разные формы? Если так, то это глупо.

Конечно, многое еще глупо, я только разбираюсь для себя, как это все работает. Со временем разберусь, от простого к сложному.
Форма одна, но массив из нее я раздробила на 5 переменных, во-первых, мне так легче сейчас понимать, что происходит,
а во-вторых, мне почему-то показалось, что так поиск будет работать корректней.
Наверняка есть лучший способ, но пусть хотя бы так заработает для начала.


>Это пример, но суть, о которой я говорил выше, в этом - массив (именно массив, а не строка разделенная запятыми) из списка, сравнивается с массивом полученным из формы.

Да, вот тут меня что-то смущает.
Если он возвращает все пересечения, то он мне вернет и то, что мне не нужно.
Например, имя Василий, фамилие Люба.
А искалось имя "Люба". И тогда и с Василием получается пересечение. Или я тут не права, насколько я успела пробежаться по мануалам, мне показалось именно так?

Потом, почему я еще склоняюсь к preg_match. Если строка пришла пустая, то ей проверкой можно присвоить " /* " - или не помню щас, как там было, чтобы этот порядковый элемент не сравнивать.

>PS. Если я прав по вопросу выше (о пяти разных формах), то вы уж опишите подробнее, что и как, что и с чем.... Сдается, что у вас лишнее на вашей кухне.

Щас вот вроде получился упрощенный пример:


<?php
$a
=array("gun""goos""grey");

$array1[0] = array ( "green""yellow""red");
$array1[1] = array ( "gun""goos""grey");
$array1[2] = array ( "gu""gos""gey");


foreach(
$array1 as $key => $value){ 
  foreach(
$value as $per) echo"<li> $per";
echo
"<br><br>";

foreach(
$a as $val)
 if (
preg_match("/^($val)$/i"$per)) {
   
$print = (array_values($array1[$key]));
                                    }
}

echo
"<br><br>";
foreach(
$print as $value) echo"<li> $value";
?>


Не, не получился(

  Ответить  
 
 автор: sim5   (25.06.2010 в 20:26)   письмо автору
 
   для: Jenshina   (25.06.2010 в 19:27)
 

Ну а для рег. выражению вы ведь тоже будете задавать условие "и Вася и Люба", причем рег выражение совсем не понимает, что Люба, это фамилие, а не имя.
Потому я и говорил, что такие вещт нужно деражать не в файле, а в таблице и скать по полям ее. Собственно функций персечений массива не одна, и есть среди них те, которые учиьывают и ключи массива.

  Ответить  
 
 автор: Jenshina   (25.06.2010 в 20:33)   письмо автору
 
   для: sim5   (25.06.2010 в 20:26)
 

>Ну а для рег. выражению вы ведь тоже будете задавать условие "и Вася и Люба", причем рег выражение совсем не понимает, что Люба, это фамилие, а не имя.


не обязательно, условие может быть просто "Люба"

>Потому я и говорил, что такие вещт нужно деражать не в файле, а в таблице и скать по полям ее. Собственно функций персечений массива не одна, и есть среди них те, которые учиьывают и ключи массива.


Буду читать сейчас внимательнее про функции.

  Ответить  
 
 автор: Jenshina   (25.06.2010 в 20:10)   письмо автору
 
   для: sim5   (25.06.2010 в 18:06)
 


foreach($a as $v) array_push($m, array_map('trim', explode(',',$v))); 

А что делает вот эта штука? Что-то не могу понять


>PS. Если я прав по вопросу выше (о пяти разных формах), то вы уж опишите подробнее, что и как, что и с чем.... Сдается, что у вас лишнее на вашей кухне.

форма такая:

<form action="form_process_searching.php" method="post">

  <p>Регион:
    <input type="text" name="reg"> 
    Метро/Район:
    <input type="text" name="mtr_ryn"> 
    улица:
    <input type="text" name="strt"> 
    комнат:
    <input type="text" name="kol_kom">
</p>
  <p>№ дома:
    <input type="text" name="nomer"> 
    Общаяя площадь:
    <input type="text" name="obsh_pl"> 
    цена:
    <input type="text" name="cena">


    <input type="submit" name="submit" value="найти">
              </p>
  </form>

код такой:

<?php

$region 
$_POST['reg'];
$metro_rayon $_POST['mtr_ryn'];
$street $_POST['strt'];
$komnat $_POST['kol_kom'];
$nomer_doma $_POST['nomer'];
$obshaya_pl $_POST['obsh_pl'];
$cena $_POST['cena'];

$peremen = array($region,$metro_rayon,$street,$komnat,$nomer_doma,$obshaya_pl,$cena);
$result count($peremen);
echo 
$result."<br>";

$file "massiv.txt";

if (
is_file($file)):
{
  
$fp fopen($file"r") ;
  
$file_array file("massiv.txt"); // Считывание файла в массив $file_array-считывается  

fclose($fp); 
}

else: 
print 
"The file $file does not exist or it is not a valid file!";
endif;
echo 
"<br>";

 
$podmassiv array_chunk($file_array,$result);//делит на подмассив 

foreach ($podmassiv as $key => $value){
  foreach (
$value as $pers);
      foreach (
$peremen as $per)
 if (
preg_match("/^($per)$/i"$pers)){
 
$print = (array_values($podmassiv[$key]));}
         
}

echo 
"<ul>" ;
  foreach (
$print as $value) echo"<li> $value";
echo 
"</ul>";

?>

  Ответить  
 
 автор: sim5   (25.06.2010 в 20:38)   письмо автору
 
   для: Jenshina   (25.06.2010 в 20:10)
 

foreach($a as $v) array_push($m, array_map('trim', explode(',',$v)));
обходит в цикле массив строк полученных из файла, разбивает строку на массив, убирает крайние пробелы в элементах полученного массива, и вставлят этот массив в массив $m.

Остальное, я уже сказал выше - не к чему вам рег. выражения. Они нежуны для сложных поисков, а вам нужно искать фамилие, имена и т.п.. Достаточно добавить ключи в массивы и все можно решить.
А вообще, бросьте эту затею, и начинайте сразу с представления своих данных в базе, и поиска в ней. Это полезней будет, ибо ваши данные, это табличные данные.

  Ответить  
 
 автор: Jenshina   (25.06.2010 в 23:38)   письмо автору
 
   для: sim5   (25.06.2010 в 20:38)
 

>Остальное, я уже сказал выше - не к чему вам рег. выражения. Они нежуны для сложных поисков, а вам нужно искать фамилие, имена и т.п.. Достаточно добавить ключи в массивы и все можно решить.


Спасибо большое!
Так действительно проще и работает.
Но вот если получать данные из формы, не работает.(

  Ответить  
 
 автор: sim5   (26.06.2010 в 09:37)   письмо автору
 
   для: Jenshina   (25.06.2010 в 23:38)
 

Не обрамляйте текст, который вы хотите процитировать, да и любой свой текст (кроме кода) ВВ-тегами [сode][/сode]. Вы же видите, что это превращается в одну строку, а прокручивать страницу по горизонтали для того чтобы прочитать, это просто неудобно. Вас за это:
а) либо обругают;
б) либо просто будут игнорировать ваши сообщения.
Если и возникает необходимость вставки простого текста (не кода) в эти теги, то разбейте его на несколько строк, при необходимости можно и отредактировать, если появляется горизонтальная прокрутка. Помните, что если на ваш пост ответили, вы уже не сможете отредактировать такую свою "портянку".
Цитируйте проще:
>Остальное, я уже сказал выше - не к чему вам рег. выражения. Они нежуны для сложных поисков...
Такого вполне достаточно будет.
Это была преамбула. )

Все будет работать, если сравнивать и с данными полученными из формы. Выше я выставлял пример с формой, который работает. В этом примере можно реализовать два условия сравнения: если любое совпадение (ИЛИ), и если все (И). Единственное, что нужно учитывать, это то, что сравниваются значения массивов, и конечно, если "Вася" имеет фамилию "Люба" (очень экзотично, конечно, но а вдруг :)), то можно получить совсем не то, чего хотелось бы.
Но если применять для сравнения функцию array_intersect_assoc, которая не просто сравнивает значения элементов массива, но и соответствие их ключей, то будем получать именно то, что требуется, при этом также остается возможность задавать логику сравнения - И/ИЛИ. Для этого файл с данными должен содеражть не только записи фамилий, имен, и т.д., но и ключи, причем эти ключи должны быть такими же как и соответствующие имена полей у формы. Записывать ключ=>значение в строке конечно можно, и разбить потом эту строку на ассоциативный массив тоже можно, но лучше так не поступать. Лучше записывать в файл сериализованный массив, а для работы извлекать его и помещать в сессию, если работать с ним необходимо не на одной странице, иначе просто извлекать в переменную. Новые записи добавляются в этот массив, опять сериализация и сохранение в файл.
Кроме этого нужно учитывать еще то, что функции пересечения массивов выполняют сравнение по строгому соответствию, то есть "Вася" не будет равно "вася" (поэтому, кстати, и удаляются крайние пробелы в значениях элементов массива формы и записей в файле). Это означает, что при сравнении двух массивов, нужно, например, переводить их значения в нижний регистр (считая, что записи ключей в списке строго соответствуют именам полей формы), так как пользователь может написать имя/фамилию любым регистром в любой позиции.

Если все это соблюсти, то все будет работать, но...
Знать наличие функций работы с массивами, их назначение и возможности, это конечно очень полезно, ибо работать с массивами придется часто, хотя бы потому, что форма от пользователя, это уже массив. Прежде, чем методично перебирать такой массив, решая некую задачу, полезно заглянуть в список функций, возможно есть среди них та, что поможет решить эту задачу проще.
Это несомненно полезно, и ваши "изыскания" тоже будут полезны как пример для освоения функций работы с массивами, открытия в них "изюминок", которые явно вроде бы и не видны из описания их работы. Но для реального скрипта, который будет работать на сервере, и который должен хранить данные о человечиках, производить поиск по этим данным, выше изложенный пример никак не пойдет. Не буду вас убеждать бросить затею с массивами и с текстовым файлом, лучше уж самой убедиться в том, что такое возможно только если данных мало, да и условий поиска не много, но если все возрастет, то... Собственное понимание ошибочности рассуждения и причин ошибок гораздо весомее и полезнее, так что дерзайте.
Единственное, что можно сказать, это то, что таблица содержащая такие же самые данные, это по структуре тот же самый массив, который и в файле содержится. Но вот по удобству поиска и получения результатов его, массив с таблицей никак не сравнить, лидером в этом является таблица. Вот почему вам стоит задуматься именно над таким представлением и хранением данных. Простой пример - пользователь знает, что фамилия начинается с "Иван", но полностью или "Иванова", или "Иванчикова", или "Ивантеева", ...? И в массиве можно сделатаь такой поиск, но в случае с базой будет проще и удобнее.
И последнее - не кидайтесь в крайности, помните всегда, что разбор рег. выражениями, это затратные операции, и прежде чем их применять, посмотрите внимательно и подумайте, вполне возможно, что есть решение, которое позволит избежать их. И если есть, значит решайте задачу без них.

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования