Search script improvement

08-18-06, 06:42 PM
|
|
Newbie Coder
|
|
Join Date: Jul 2006
Posts: 86
Thanks: 0
Thanked 0 Times in 0 Posts
|
|
|
Search script improvement
This piece of code searches the $info field of my delimited text file database:
PHP Code:
foreach ($file as $line => $data)
{
list($month, $day, $year, $info) = explode('|', trim($data) );
if (stristr($info, $search))
{
echo $info;
}
}
I have 3 Questions:
1) Lets say a person was searching for "John Smith" they could enter "John Smith" or "John" or "Smith" and it would work. I would like to improve my search so that if a person searched for "John Smith" it would also find results for "John T. Smth" or " John Q. Smith" etc. Is there an easy way to do this?
2) How can I sort the $year field?
3) For each record, the data in my $info is 2 or 3 sentences long. When the current script returns a result, there is only 1 space between sentences even though there are 2 in my database. Any suggestions on how I can fix this?
Thanks in advance
|

08-19-06, 05:35 AM
|
 |
Community VIP
|
|
Join Date: May 2005
Location: Antwerp, Belgium
Posts: 2,724
Thanks: 0
Thanked 0 Times in 0 Posts
|
|
possible answers to your questions:
1. you could split the search-query, by using the whitespace. then you have to loop over the search-options, during the foreach loop:
PHP Code:
$search = explode(' ', $search);
foreach ($file as $line => $data)
{
list($month, $day, $year, $info) = explode('|', trim($data) );
for($i=0; $i<sizeof($seach); $i++){
if (stristr($info, $search[$i]))
{
echo $info;
}
}
}
2. instead of overwriting the same variables (list($month, $day, $year, $info)), you have to use them as an array. then use the sort() function to sort the array. This way you will have to double loop over your data, as you can't display for the search query an sort the array at the same time. then the year wouldn't be displayed ordered.
3. Do you mean newlines or just whitespace? if it's just whitespace, use the str_replace function to replace ' ' by ' ', then there should be no problem. if it's newlines, then i have no idea.
Greetz,
UnrealEd
__________________
"Good judgement comes from experience, and experience comes from bad judgement." - Fred Brooks
If you want to add me on any IM, pm me first
|

08-19-06, 06:09 AM
|
 |
Community Leader
|
|
Join Date: Sep 2005
Location: Spain
Posts: 7,572
Thanks: 5
Thanked 27 Times in 24 Posts
|
|
A bit too late... but anyways.
PHP Code:
<?php
$search = $_POST['search'];
$file = file('data.txt');
$keys = preg_split('/[\s,]+/', preg_replace('/(^\s+|\#|\/|\'|\"|\~|\^|\.|\+|\$|\s+$)/', '', $search) );
if (sizeof($keys) > 5)
{
die("Please enter less keywords");
}
$pattern = '/('. implode('|', $keys) .')/i';
$matches = array();
foreach ($file as $line => $data)
{
list($month, $day, $year, $info) = explode('|', trim($data) );
if (preg_match($pattern, $info))
{
$matches[$year][] = preg_replace($pattern, '<span style="color:red;">$1</span>', $info);
}
}
ksort($matches);
print_r($matches);
?>
Last edited by nico_swd; 08-19-06 at 06:20 AM.
|

08-19-06, 10:52 AM
|
|
Newbie Coder
|
|
Join Date: Jul 2006
Posts: 86
Thanks: 0
Thanked 0 Times in 0 Posts
|
|
Hey nico I tried yours first because it seemed like it coverd all 3 questions but I get something like this when I run it:
Array ( [0] => [1] => [2] => [3] => [4] => [5] => [6] => [7] => [8] => [9] => [10] => [11] => [12] => [13] => [14] => [15] => ) [2000] =>
Also, how does the
PHP Code:
print_r($matches);
differ from what I used in the past if I wanted font and size selection
PHP Code:
echo '<font face="Times New Roman" size="2px">'. $info .'</font>';
echo "<p>";
Thanks All
|

08-19-06, 11:19 AM
|
 |
Community Leader
|
|
Join Date: Sep 2005
Location: Spain
Posts: 7,572
Thanks: 5
Thanked 27 Times in 24 Posts
|
|
Well, it was more of an example. Give this a try:
PHP Code:
<?php
$search = $_POST['search'];
if ($search)
{
$file = file('data.txt');
$keys = preg_split('/[\s,]+/', preg_replace('/([^a-z0-9\s])/i', '', trim($search) ) );
if (sizeof($keys) > 5)
{
die("Please enter less keywords");
}
else if (empty($keys[0]))
{
die("Please enter a valid keyword.");
}
$pattern = '/('. implode('|', $keys) .')/i';
$matches = array();
foreach ($file as $line => $data)
{
list($month, $day, $year, $info) = explode('|', trim($data) );
if (preg_match($pattern, $info))
{
$matches[$year][] = preg_replace($pattern, '<span style="color:red;">$1</span>', $info);
}
}
if (sizeof($matches) > 0)
{
ksort($matches);
printf('<p>%d match%s found.</p>', sizeof($matches), sizeof($matches) == 1 ? NULL : 'es');
echo '<ol>';
foreach ($matches AS $year => $match)
{
echo '<li><font face="Times New Roman" size="2px">'. $year .': '. current($match) .'</font></li>'. "\n";
}
echo '</ol>';
}
else
{
echo '<p>No matches found.</p>';
}
}
?>
<form action="" method="post">
<input type="text" name="search" />
<input type="submit" value="Search" />
</form>
Last edited by nico_swd; 08-19-06 at 01:05 PM.
|

08-19-06, 11:40 AM
|
|
Newbie Coder
|
|
Join Date: Jul 2006
Posts: 86
Thanks: 0
Thanked 0 Times in 0 Posts
|
|
Thanks nico, seems to work well.
|

08-19-06, 01:49 PM
|
|
Newbie Coder
|
|
Join Date: Jul 2006
Posts: 86
Thanks: 0
Thanked 0 Times in 0 Posts
|
|
I adapted your code to fit my needs (such as: I replaced the ordered list with a $count variable because I didn't want the indentation), however, I have 3 Questions.
1) I am not real familar to patern matching etc. In the code you gave me, is it restrictive in any way? What I mean is that for some searches I get less results than I dowith using the stristr as I did earlier.
2) In my first echo line, I want to display the month, year and date associated with that record. I tried this:
PHP Code:
echo '<center><b><font face="Times New Roman" size=2px">' . $count. '--' . $month . ' ' . $day . ', ' . $year . '</font></b></center>';
but it prints December 31 for every enrty. The year is correct though. What did I do wrong?
3) I want to restrict the search results to a number, say, 200. I play around with:
PHP Code:
if ((sizeof($matches) > 0) AND (sizeof($matches) < 200))
but that returns no values. How did I screw that up?
Here is a snippet of the complete code:
PHP Code:
$file = file('data.txt');
$keys = preg_split('/[\s,]+/', preg_replace('/(^\s+|\#|\/|\'|\"|\~|\^|\.|\+|\$|\s+$)/', '', $search) );
$count = 0;
if (sizeof($keys) > 5)
{
die("Please enter less keywords");
}
$pattern = '/('. implode('|', $keys) .')/i';
$matches = array();
foreach ($file as $line => $data)
{
list($month, $day, $year, $info) = explode('|', trim($data) );
if (preg_match($pattern, $info))
{
$matches[$year][] = preg_replace($pattern, '<span style="color:red;">$1</span>', $info);
}
}
ksort($matches);
if (sizeof($matches) > 0)
{
printf('<p>%d match%s found.</p>', sizeof($matches), sizeof($matches) == 1 ? NULL : 'es');
foreach ($matches AS $year => $match)
{
$count++;
echo '<center><b><font face="Times New Roman" size=2px">' . $count. '--' . $month . ' ' . $day . ', ' . $year . '</font></b></center>';
echo '<font face="Times New Roman" size="2px">' . current($match) .'</font>';
echo "<p>";
}
}
else
{
echo "No results were found for your search--Please try again";
}
|

08-19-06, 03:12 PM
|
 |
Community Leader
|
|
Join Date: Sep 2005
Location: Spain
Posts: 7,572
Thanks: 5
Thanked 27 Times in 24 Posts
|
|
Okay, give this a try.
PHP Code:
<?php
$search = $_POST['search'];
if ($search)
{
$file = file('data.txt');
$keys = preg_split('/[\s,]+/', preg_replace('/([^a-z0-9\s])/i', '', trim($search) ) );
if (sizeof($keys) > 5)
{
die("Please enter less keywords");
}
else if (empty($keys[0]))
{
die("Please enter a valid keyword.");
}
$pattern = '/('. implode('|', $keys) .')/i';
$matches = array();
foreach (array_values($file) AS $data)
{
list($month, $day, $year, $info) = explode('|', trim($data) );
if (preg_match($pattern, $info))
{
$matches[mktime(0, 0, 0, $month, $day, $year)][] = preg_replace($pattern, '<span style="color:red;">$1</span>', $info);
}
}
if (sizeof($matches) > 0)
{
ksort($matches);
$count = 0;
printf('<p>%d match%s found.</p>', sizeof($matches), sizeof($matches) == 1 ? NULL : 'es');
echo '<ol>';
foreach ($matches AS $time => $match)
{
list($month, $day, $year) = explode('-', date('M-d-Y', $time) );
$count++;
echo '<center><b><font face="Times New Roman" size=2px">' . $count. '--' . $month . ' ' . $day . ', ' . $year . '</font></b></center>';
echo '<font face="Times New Roman" size="2px">' . current($match) .'</font>';
echo "<p>";
if ($count >= 200)
{
break;
}
}
echo '</ol>';
}
else
{
echo '<p>No matches found.</p>';
}
}
?>
<form action="" method="post">
<input type="text" name="search" />
<input type="submit" value="Search" />
</form>
Quote:
|
1) I am not real familar to patern matching etc. In the code you gave me, is it restrictive in any way? What I mean is that for some searches I get less results than I dowith using the stristr as I did earlier.
|
Hm, actually it should do the same, even better. It splits the string on every whitespace and searches for every word, case insensitive.
Quote:
|
2) In my first echo line, I want to display the month, year and date associated with that record. I tried this:
|
Cause these variables are the ones from the previous loop. They contain always the same values after the last loop.
The code above should do everything you want.
|

08-19-06, 04:57 PM
|
|
Newbie Coder
|
|
Join Date: Jul 2006
Posts: 86
Thanks: 0
Thanked 0 Times in 0 Posts
|
|
Okay, now it is showing different Months and Days but they don't correspond to the month and day field from the record in which it came. The year does not either. Also, in some cases, all the results are not returned.
|

08-21-06, 04:57 AM
|
 |
Community Leader
|
|
Join Date: Sep 2005
Location: Spain
Posts: 7,572
Thanks: 5
Thanked 27 Times in 24 Posts
|
|
Ah yeh, I guess cause you're not storing the date format as I expected, and also it didn't go through all matches in the array. Give this a try:
PHP Code:
<?php
$search = $_POST['search'];
if ($search)
{
$file = file('data.txt');
$keys = preg_split('/[\s,]+/', preg_replace('/([^a-z0-9\s])/i', '', trim($search) ) );
if (sizeof($keys) > 5)
{
die("Please enter less keywords");
}
else if (empty($keys[0]))
{
die("Please enter a valid keyword.");
}
$pattern = '/('. implode('|', $keys) .')/i';
$matches = array();
$matchcount = 0;
foreach (array_values($file) AS $data)
{
list($month, $day, $year, $info) = explode('|', trim($data) );
if (preg_match($pattern, $info))
{
$matches[strtotime("$day $month $year")][] = preg_replace($pattern, '<span style="color:red;">$1</span>', $info);
$matchcount++;
}
}
if (sizeof($matches) > 0)
{
ksort($matches);
$count = 0;
printf('<p>%d match%s found.</p>', $matchcount, $matchcount == 1 ? NULL : 'es');
echo '<ol>';
foreach ($matches AS $days => $event)
{
foreach ($event AS $tip)
{
list($month, $day, $year) = explode('-', date('M-d-Y', $days) );
$count++;
echo '<center><b><font face="Times New Roman" size=2px">' . $count. '--' . $month . ' ' . $day . ', ' . $year . '</font></b></center>';
echo '<font face="Times New Roman" size="2px">' . $tip .'</font>';
if ($count >= 2)
{
break;
}
}
if ($count >= 2)
{
break;
}
}
echo '</ol>';
}
else
{
echo '<p>No matches found.</p>';
}
}
?>
<form action="" method="post">
<input type="text" name="search" />
<input type="submit" value="Search" />
</form>
Last edited by nico_swd; 08-21-06 at 05:31 AM.
|
|
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
|
|
|
| Thread Tools |
|
|
| Display Modes |
Linear Mode
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
|