PHP: How to find a big word in a small one - php

I have user input like:
$name = 'Alexxxx'
Or
$name = 'Aaaalex'
And I have list of names like:
$names = 'Jack Harry Alex Oscar'
I need to know that user input contains name from a list, but user can input 'raw' name. How I can check it?
I've tried variants like this. But all of this find half input name in List. While I need the other way around
preg_match(
'/(.*)' . $name . '(.*)/',
$this->listOfNames,
);
str_contains(
$this->listOfNames, strtolower(trim($name))
);
strstr($this->listOfNames, $name) !== false;

I'm hoping that I've understood correctly, if not, please do correct me in comments!
My understanding is that you want to know whether a user-inputted string contains at least one of the names listed in a string (separated by a space). For example, search Alexxxx for Jack Harry Alex or Oscar which is of course true because Alexxxx contains Alex.
On the other hand, inputting Bruno would return false.
If I've understood correctly, the key would be to split the string of names using explode by the space as delimiter, then iterate through each item checking it against the inputted string.
<?php
$inputName = 'Alexxxx';
$names = 'Jack Harry Alex Oscar';
//Get an array of the names from $name. Result: ["Jack","Harry","Alex","Oscar"]
$listOfNames = explode(" ", $names);
// Initially we're going to filter our new array ($listOfNames)
// and pass in the $inputName using "use".
// The filter callback merely checks for string position using strpos,
// case insensitivity requires stripos.
// This will return ["Alex"] is this example.
// A simple count() > 0 logic check will give us a true/false outcome
// stored in $inputFoundInList. count() will be zero is not found.
$inputFoundInList = count(array_filter($listOfNames, function ($name) use ($inputName) {
return strpos($inputName, $name) !== FALSE;
})) > 0;
// Result will be 1 (or true)
echo $inputFoundInList;

Related

Find out if string matches array key, return value for that key

I am working on an import script that needs to evaluate whether the set string fits with the possible values the backend field can have.
More exactly what I have is this array of committes:
$committees = array(
'Ämter' => 1,
'Abteilungen' => 2,
'Konservatoren' => 3,
'Dienstagssitzung' => 4,
);
and now I need to figure out if a string saved in
variable $category matches any key in that array. If it does match one of the entries, I need it to return the value (1, 2, 3 or 4) that goes with that key.
I read up about it here on Stackoverflow and found plenty examples to see if a value equals one in an array, for example:
preg_match array items in string?
and tried to follow those along.
I tried
$committeesKeys = '/(' . implode('|', array_keys($committees)) . ')/';
$matches = preg_match($committeesKeys, $category);
but that only returned how many matches it found?
I also tried
$input = preg_quote($category, '/');
$matches = preg_filter('/'.$input.'/', null, $committees);
as that was suggested somehwere else, can't find the link anymore, but that returned an empty array.
I am new to all of this so might be totally wrong here.
Can anybody tell me how I can do this, or where I can find an answer to the question? I might just not have found it, my brain is rather tired right now...
I feel that I have right to post that as answer accepted :-) :
echo (isset($committees[$category]))?$committees[$category]:'There is no '.$category.' category';
you can do something like this:
function getValue($category){
if (array_key_exists($category, $committees)){
return $committees[$category]; //the value you want
}
}
Hope this helps :)
preg_match() has a 3rd argument which will allow you to save capture groups into a numerical array. However, if you want to compare a string directly you can simply use a loop and strcmp or === which will probably work faster since preg_match has to compile the regex you define in the first argument. My solution for this problem would look like:
$found = FALSE;
foreach ( $committees as $name=>$number ) {
if ( $name === $category ) {
$found = $number;
}
}
return $found;
You make it difficult by not showing what is in the category matches.
Maybe something like this.
$results = array_intersect ($matches,$committees );

Why the output is not a string

I tried many time, but I still don't understand why the output is not a string, anything wrong ? help me check it. The final output should be a uppercase name string
<html>
<p>
<?php
// Create an array and push on the names
// of your closest family and friends
$name = array();
array_push($name,"Mike");
array_push($name,"Jane");
array_push($name,"Jack");
array_push($name,"Nike");
array_push($name,"Ash");
array_push($name,"Chris");
array_push($name,"Zark");
// Sort the list
sort($name);
join(",",$name);
// Randomly select a winner!
$random = count($name,rand(0,7));
// Print the winner's name in ALL CAPS
$winner = strtoupper($random);
print($winner);
?>
</p>
</html>
$random = count($name,rand(0,7));
This line assigns the count of elements in $name. I don't know what else you expected to get back other than a number here.
What you really want:
echo strtoupper($name[array_rand($name)]);
http://php.net/manual/en/function.array-rand.php
Other Notes:
Your call to join() doesn't do anything useful since you're not doing anything with the return value.
Your call to sort is pointless if you're just picking a random entry later.
Pick a plural name for your array names so you know they are arrays. $names instead of $name.
If you know all of the array elements ahead of time, no need for array_push(), just use an array literal: array('Mike', 'Jane', /* etc */)
If you're outputting data into the context of HTML, always use htmlspecialchars() to make sure any reserved characters are escaped properly. This isn't a problem with the code you literally have here, but will be as soon as you want to output < or ".

Compare PHP arrays

I know there are a lot of these, but I'm looking for something slightly different.
A straight diff won't work for me.
I have a list (array) of allowed tags i.e. ["engine","chassis","brakes","suspension"]
Which I want to check with the list the user has entered. Diff won't work, because the user may not enter all the options i.e. ["engine"] but I still want this to pass. What I want to happen is fail if they put something like "banana" in the list.
You can use array_intersect(), and check the size of the resulting array with the size of the input array. If the result is smaller, then the input contains one or more items not in the 'allowed' array. If its size is equal, all items in it are in the user's input, so you can use the array do do whatever you want.
Use array_diff();
$allowed=array("engine","chassis","brakes","suspension");
$user=array("engine","brakes","banana");
$unallowed=array_diff($user, $allowed);
print_r($unallowed);
This will return banana, as it is in $user, but not in $allowed.
array_diff(): http://nl.php.net/array_diff
Returns an array containing all the entries from array1 that are not present in any of the other arrays.
if ( array_diff( $input, $allowed ) ) {
// error
}
$allowed_tags = array("engine","chassis","brakes","suspension");
$user_iput = array("engine", "suspension", "banana");
foreach($user_input as $ui) {
if(!in_array($ui, $allowed_tags)) {
//user entered an invalid tag
}
}

Collect keyword from text string and insert into database automatically PHP MySql

I need help to create a script for finding keywords in a string, and inserting them into a database for use in a tag cloud.
The script would need to obviously dismiss characters, and common words like 'I', 'at', 'and', etc.
Get a value for the frequency of each keyword it finds and then insert it into the database if it's new, or update the existing row with the addition of the strings keyword count.
The string is unformatted text from a database row.
I'm not new to PHP, but I haven't attempted anything like this before, so any help is appreciated.
Thanks, Lea
Google + php keywords from text = http://www.hashbangcode.com/blog/extract-keywords-text-string-php-412.html
Well, the answer is already there, I still post my code for the little work that has gone into it.
I think that a mysql db is not ideal for storing this kind of data. I would suggest something like memcachedb, so you can easily access a keyword by using it as an index to fetch the count from the db. Persisting those keywords in a high load environment may cause problems with a mysql db.
$keyWords = extractKeyWords($text);
saveWords($keyWords);
function extractKeyWords($text) {
$result = array();
if(preg_match_all('#([\w]+)\b#i', $text, $matches)) {
foreach($matches[1] as $key => $match) {
// encode found word to safely use as key in array
$encodedKey = base64_encode(strtolower($match));
if(wordIsValid($match)) {
if(array_key_exists($encodedKey, $result)) {
$result[$encodedKey] = ++$result[$encodedKey];
} else {
$result[$encodedKey] = 1;
}
}
}
}
return $result;
}
function wordIsValid($word) {
$wordsToIgnore = array("to", "and", "if", "or", "by", "me", "you", "it", "as", "be", "the", "in");
// don't use words with a single character
if(strlen($word) > 1) {
if(in_array(strtolower($word), $wordsToIgnore)) {
return false;
} else {
return true;
}
} else {
return false;
}
}
// not implemented yet ;)
function saveWords($arrayOfWords) {
foreach($arrayOfWords as $word => $count) {
echo base64_decode($word).":".$count."\n";
}
}
You could approach this with a dictionary of keywords or a dictionary of words to ignore. If you make a dictionary of key words then count each time one is used and then update a database table with the keywords. If you make a dictionary of words to ignore then strip those words from posts and insert or update a count for all the remaining words into the keyword table.
The way does it is by storing every word entered in every post in a table. When people search the forum, the result is the post IDs from which the words came.I suggest something like this.
Compare a user submission with your array of blacklisted (obvious) words which would come from a database table. THe words that survive are your keywords. Enter those keywords into your database table. Then use a SELECT * statement from your table to return a result set. Use the array_count function as demonstrated to get your count.
Perhaps a better way is to do what most sites do and force the user to enter their keywords (Stackoverflow, delicious, etc.) That way you can skip all the parsing up front.
If the string is not too long and you won't have memory issues with storing the string in arrays, how about this?
# string to parse, comes from the database as you suggested
$string = 'I at and Cubs PHP Cubs';
# string is now an array
$stringArray = explode(" ", $string);
# list of "obvious" words to exclude, this would probably come from a database table
$wordsToExclude = array('I', 'at', 'and');
# array that contains your "keywords"
# Array('Cubs', 'PHP', 'Cubs')
$keywordArray = array_diff($stringArray, $wordsToExclude);
# array with the keyword as the key and the count as the value
# Array('Cubs' => 2, 'PHP' => 1)
$countedValues = array_count_values($keywordArray);
Now you need to "search" the database for the keys in the $countedValues array. What does your table look like?
Or of course you could avoid reinventing the wheel and Google "php tag cloud"...
Reference: PHP array functions

How do I detect groups of common strings in filenames

I'm trying to figure out a way to detect groups of files. For instance:
If a given directory has the following files:
Birthday001.jpg
Birthday002.jpg
Birthday003.jpg
Picknic1.jpg
Picknic2.jpg
Afternoon.jpg.
I would like to condense the listing to something like
Birthday ( 3 pictures )
Picknic ( 2 pictures )
Afternoon ( 1 picture )
How should I go about detecting the groups?
Here's one way you can solve this, which is more efficient than a brute force method.
load all the names into an associative array with key equal to the name and value equal to the name but with digits stripped (preg_replace('/\d//g', $key)).
You will have something like $arr1 = [Birthday001 => Birthday, Birthday002 => Birthday ...]
now make another associative array with keys that are values from the first array and value which is a count. Increment the count when you've already seen the key.
in the end you will end up with a 2nd array that contains the names and counts, just like you wanted. Something like $arr2 = [Birthday => 2, ...]
Simply build a histogram whose keys are modified by a regex:
<?php
# input
$filenames = array("Birthday001.jpg", "Birthday002.jpg", "Birthday003.jpg", "Picknic1.jpg", "Picknic2.jpg", "Afternoon.jpg");
# create histogram
$histogram = array();
foreach ($filenames as $filename) {
$name = preg_replace('/\d+\.[^.]*$/', '', $filename);
if (isset($histogram[$name])) {
$histogram[$name]++;
} else {
$histogram[$name] = 1;
}
}
# output
foreach ($histogram as $name => $count) {
if ($count == 1) {
echo "$name ($count picture)\n";
} else {
echo "$name ($count pictures)\n";
}
}
?>
Generate an array of words like "my" (developing this array will be very important, "my" is the only one in your example given) and strip these out of all the file names. Strip out all numbers and punctuation, also extensions should be long gone at this point. Once this is done, put all of the unique results into an array. You can then use this as a fairly reliable source of keywords to search for any stragglers that the other processing didn't catch.

Categories