Compare two sentences sequence wise - php

The scenario is there is a given sentence. The user have to type in the sentence in some input field and that will be saved to database.
Now, I want to compare both the sentences and find out, how many words the user has typed in correctly and incorrectly (missed any word, or added some new words by typing mistake).
Now I have done something like this-
$Str1 = "i **am** suraj roy i **am** having my lunch";
$Str2 = "i suraj roy i **am** having my dinner";
$st1 = (explode(" ", $Str1));
$st2 = (explode(" ", $Str2));
$result1 = array_diff($st1, $st2);
$result2 = array_diff($st2, $st1);
$word_count1 = count($result1); // words not present in typed sentence from original sentence - lunch
$word_count2 = count($result2); // newly added words in typed sentence - dinner
$total_error_count = $word_count1 + $word_count2;
echo 'Total words not matching between two sentences - '.$total_error_count;
Now this is working as i expected. Good.
But the problem is, have a look at the word am in both sentences, as the comparison is being done between array its taking single occurrence of am in typed sentence for all the occurrence of am in original sentence. So, there is no missing word count for am in typed sentence.
So, any help would be appreciated. Thanks.

Related

How to replace matching characters in two sets of strings with bolded characters?

currently working on a following function:
public function boldText($searchSuggestions)
{
$search = $this->getRequestParameter('search');
$pattern = "/".$search."/u";
$searchSuggestions = preg_replace($pattern, '<b>'.$search.'</b>', $searchSuggestions);
echo $searchSuggestions;
}
Let's say $searchSuggestions = hello
While the user is typing in the search box, which in this case the variable $search contains this input, a dropdown menu of all possible result suggestions are displayed. If a user types 'hello', then the search results like 'helloworld' or 'hello2' would pop up and the inputted word, int this case 'hello' would be bold in all outputted search results. So far it is working fine, however, big Characters are being replaced with small Characters and vice versa in the outputted search results. I have a feeling that the underlying problem might be in this function, however I am not entirely sure. If anyone has any suggestions or tips on where to look, it would be great!
If I should give out more info please do let me know, and I will edit the question immediately.
Thankyou!
Example output currently -
User types in search bar - 'hello'
result shown should be - 'Hello'
result actually being shown - 'hello'
P.S The results are accessed from an sql query. If a user types, than a query that gets data related to the words inputted is shown. For instance - 'SELECT * FROM test WHERE example LIKE '%hello%'
In database one can find the word Hello. Note the H has a big character.
I tried this following code
public function boldText($searchSuggestions)
{
$search = $this->getRequestParameter('search');
$pattern = "/".$search."/u";
$searchSuggestions = preg_replace($pattern, '<b>'.$search.'</b>', $searchSuggestions);
echo $searchSuggestions;
}
Brief Explanation
$searchSuggestions
Hello
$search(being typed by the user)
h
The output should be
<b>H</b>ello
The output I am currently getting is
<b>h</b>ello
I tried to look further on how to properly solve this and it was a bit simpler than I expected. Did not have to use preg_replace for this. The following code did the trick for me:
public function boldText($searchSuggestions)
{
$search = $this->getRequestParameter('search');
$lastPosition = strlen($search);
$firstPosition = stripos($searchSuggestions, $search);
$replacement = substr($searchSuggestions, $firstPosition, $lastPosition);
$searchSuggestions = substr_replace($searchSuggestions, '<b><u>'.$replacement.'</u></b>', $firstPosition, $lastPosition);
echo $searchSuggestions;
}
$lastPosition - we find how long the search input is, therfore getting the last position
$firstPosition - compare the two strings by finding a match(case insensitive), therefore finding the first position
$replacement - we remove what matches between search and searchSuggestion from the searchSuggestion string, with the help of the firstPosition and lastPosition variables.
At the end the searchSuggestion variable is replaced accordingly. Hope I was clear enough if not please let me know. (Answered my own question lol!)
You need to capture the found text you then can use that in the replacement bit. Your current implementation uses the input which may or may not match the case of the original string. So you should:
use the i modifier so your search is case insensitive
use word boundaries so partial matching doesn't occur
use capture group to capture the match
use preg_quote so any special regex characters don't affect regex operations
public function boldText($searchSuggestions)
{
$search = $this->getRequestParameter('search');
$pattern = "/\b(". preg_quote($search) . ")\b/iu";
$searchSuggestions = preg_replace($pattern, '<b>$1</b>', $searchSuggestions);
echo $searchSuggestions;
}
If partial word matching is intended you can remove word boundaries:
public function boldText($searchSuggestions)
{
$search = $this->getRequestParameter('search');
$pattern = "/(". preg_quote($search) . ")/iu";
$searchSuggestions = preg_replace($pattern, '<b>$1</b>', $searchSuggestions);
echo $searchSuggestions;
}
consider https://en.wikipedia.org/wiki/Scunthorpe_problem#Origin_and_history also though.

ucwords(strtolower()) not working together php

I have code where I am extracting a name from a database, trying to reorder the word, and then changing it from all uppercase to word case. Everything I find online suggests my code should work, but it does not... Here is my code and the output:
$subjectnameraw = "SMITH, JOHN LEE";
$subjectlname = substr($subjectnameraw, 0, strpos($subjectnameraw, ",")); // Get the last name
$subjectfname = substr($subjectnameraw, strpos($subjectnameraw, ",") + 1) . " "; // Get first name and middle name
$subjectname = ucwords(strtolower($subjectfname . $subjectlname)); // Reorder the name and make it lower case / upper word case
However, the output looks like this:
John Lee smith
The last name is ALWAYS lowercase no matter what I do. How can I get the last name to be uppercase as well?
The above code gives wrong results when there are multibyte characters in the names like RENÉ. The following solution uses the multibyte function mb_convert_case.
$subjectnameraw = "SMITH, JOHN LEE RENÉ";
list($lastName,$firstnName) = explode(', ',mb_convert_case($subjectnameraw,MB_CASE_TITLE,'UTF-8'));
echo $firstnName." ".$lastName;
Demo : https://3v4l.org/ekTQA

php preg_replace pattern - replace text between commas

I have a string of words in an array, and I am using preg_replace to make each word into a link. Currently my code works, and each word is transformed into a link.
Here is my code:
$keywords = "shoes,hats,blue curtains,red curtains,tables,kitchen tables";
$template = '%1$s';
$newkeys = preg_replace("/(?!(?:[^<]+>|[^>]+<\/a>))\b([a-z]+)\b/is", sprintf($template, "\\1"), $keywords);
Now, the only problem is that when I want 2 or 3 words to be a single link. For example, I have a keyword "blue curtains". The script would create a link for the word "blue" and "curtains" separately. I have the keywords separated by commas, and I would like the preg_replace to only replace the text between the commas.
I've tried playing around with the pattern, but I just can't figure out what the pattern would be.
Just to clarify, currently the output looks as follows:
shoes,hats,blue curtains,red curtains,tables,kitchen tables
While I want to achieve the following output:
shoes,hats,blue curtains,red curtains,tables,kitchen tables
A little bit change in preg_replace code and your job will done :-
$keywords = "shoes,hats,blue curtains,red curtains,tables,kitchen tables";
$template = '%1$s';
$newkeys = preg_replace("/(?!(?:[^<]+>|[^>]+<\/a>))\b([a-z ' ']+)\b/is", sprintf($template, "\\1"), $keywords);
OR
$newkeys = preg_replace("/(?!(?:[^<]+>|[^>]+<\/a>))\b([a-z' ']+)\b/is", sprintf($template, "\\1"), $keywords);
echo $newkeys;
Output:- http://prntscr.com/77tkyb
Note:- I just added an white-space in your preg_replace. And you can easily get where it is. I hope i am clear.
Matching white-space along with words is missing there in preg_replace and i added that only.

Matching words from an array causes some vulnerabilities

Suppose there is a word in an array as "pan" and user typed a sentence which
contain a word as "pants" the program matches the word "pants" as "pan" please help me out, and for further information there are also some words in the array like "my valet","the nest" etc... need to be match.Thanks in advance.:)
if($val['items']!=null){
$items = explode(',',$val['items']);
foreach($items as $k=>$item){
if($item!='' && preg_match("/".preg_quote($item,"/")."/", $opText)){
if(!in_array($item,$parameters[$val['name']],true)){
$parameters[$val['name']][]=$item;
}
}
}
}
Use a delimiter such as a space. Instead of searching for the word "pan" search for " pan ", when you search for words like "my valet" search for " my valet " instead. You also need to handle if it is the first word of the sentence in which case you ignore the first space. Does this resolve your issue?

Making one line Regular Expression

I'm making cover letters for mailing of books and magazines. I have all data of recipients in the data base and I have PHP script fetching that data and making cover letters. A user who writes that cover letter using special characters to mark where the name should be put etc.
For example, in order to compose a cover letter an user writes:
Dear [[last_name]],
please find attached book...
Then it gets parsed by PHP script and [[last_name]] tag gets replaced with a real name. When 1000 addresses selected for mailing then the script produces 1000 cover letters each one with defferent name.
Now, in my Russian language word "Dear" has different ending for male and female. It is like we say on English "Dear mr." or "Dear mrs."
In order to mark that in the cover letter user writes the possible endings for the word:
Dear[[oy/aya]] [[last_name]]
or it could be something like:
Dear[[ie/oe]]... etc.
I'm trying to figure out the regular expression and replacement command for my PHP script to parse those kind of lines.
For the last_name tags I use:
$text = ...//this is text of the cover letter with all the tags.
$res = $mysqli->query("SELECT * FROM `addresses` WHERE `flag` = 1")
while ($row=$res->fetch_assoc()) {
$text = str_replace('[[last_name]]', $row['lname'], $text);
echo $text;
}
For the word endings as I understand it should be something like:
$text = preg_replace('/\w{2-3}\//\w{2-3}/', ($row['gender']==1)
? 'regexp(first_half)'
: 'regext(second_half)', $text);
I could make this whole idea by cycling through the tag, parsing it and replace but it would be 5-10 lines of code. I'm sure this can be done just by the line above but I can't figure out how.
see http://www.phpliveregex.com/p/2BC and then you replace with $1 for male and $2 for female
...
preg_replace('~\[\[(.+?)/(.+?)\]\]~', $row['gender']==1?'$1':'$2', $text);
$gender = ($row['gender'] == 1) ? 1 : 2;
preg_replace_callback('#\[\[(?:([^\]/]+)(?:/([^\]/]+))?\]\]#',
function($match) use ($row, $gender) {
// $match will contain the current match info
// $match[1] will contain a field name, or the first part of a he/she pair
// $match[2] will be non-empty only in cases of he/she etc
return (empty($match[2])) ? $row[$match[1]] : $match[$gender];
}
);

Categories