Compare two string and ignore (but not replace) accents. PHP - php

I got (for example) two strings:
$a = "joao";
$b = "joão";
if ( strtoupper($a) == strtoupper($b)) {
echo $b;
}
I want it to be true even tho the accentuation. However I need it to ignore the accentuation instead of replacing because I need it to echo "joão" and not "joao".
All answers I've seen replace "ã" for "a" instead of making the comparison true. I've been reading about normalizing it, but I can't make it work either. Any ideas? Thank you.

Just convert the accents to their non-accented counter part and then compare strings. The function in my answer will remove the accents for you.
function removeAccents($string) {
return strtolower(trim(preg_replace('~[^0-9a-z]+~i', '-', preg_replace('~&([a-z]{1,2})(acute|cedil|circ|grave|lig|orn|ring|slash|th|tilde|uml);~i', '$1', htmlentities($string, ENT_QUOTES, 'UTF-8'))), ' '));
}
$a = "joaoaaeeA";
$b = "joãoâàéèÀ";
var_dump(removeAccents($a) === removeAccents($b));
Output:
bool(true)
Demo

I would like to share an elegant solution that avoids the usage of htmlentities and that doesn't need to manually list all chars replacements. It is the traduction in php of the answers to this post.
function removeAccents($str) {
return preg_replace('/[\x{0300}-\x{036f}]/u',"",normalizer_normalize($str,Normalizer::FORM_D));
}
$a = "joaoaaeeA";
$b = "joãoâàéèÀ";
var_dump(removeAccents($a) === removeAccents($b));
Output:
bool(true)

It's not a plain PHP solution but works very well for this situation, run this query on MySQL:
SELECT 'joão' = 'joao'
So if you have access to mysql you can use it from PHP.

Related

PHP extract comparison operator

I was asked on an interview what would be the fastest way to extract the comparison operator between two statements.
For example rate>=4 the comparison operator is '>=' it should be able to extract '>','<','!=','=','<=','>=','='
The function must return the comparison operator.
This is what I wrote, and they marked it as wrong.
function extractcomp($str)
{
$temp = [];
$matches = array('>','<','!','=');
foreach($matches as $match)
{
if(strpos($str,$match)!== false)
{
$temp[] = $match;
}
}
return implode('',$temp);
}
Does anyone have a better way?
you can read character by character once you hit the first occurrence you can determine what's gonna be the next character i.e.:
$ops = ['>','<','!','='];
$str = "rate!=4";
foreach($ops as $op)
{
if(($c1 = strpos($str, $op)) !== false)
{
$c2 = $str[$c1++] . (($str[$c1] == $ops[3]) ? $str[$c1] : "");
break;
}
}
echo $c2;
So if the first search character is ">" you can only assume the 2nd one is gonna be "=" or it doesn't exist. So you get the index of 1st character and increment it and check if the 2nd character exists in our search array or not. Then return the value. this will loop until it finds the 1st occurrence then breaks.
EDIT:
here's another solution:
$str = "rate!=4";
$arr = array_intersect(str_split($str), ['>','<','=','!']);
echo current($arr).(end($arr) ? end($arr) : '');
not as fast as the loop but definitely decreases the bloat code.
There's always a better way to optimize the code.
Unless they have some monkeywrenching strings to throw at this custom function, I recommend trim() with a ranged character mask. Something like echo trim('rate>=4',"A..Za..z0..9"); would work for your sample input in roughly half the time.
Code: (Demo)
function extractcomp($str){
return trim($str,"A..Za..z0..9");
}
echo extractcomp("rate>=4");
Regarding regex, better efficiency in terms of step count with preg_match() would be to use a character class to match the operators.
Assuming only valid operators will be used, you can use /[><!=]+/ or if you want to tighen up length /[><!=]{1,3}/
Just 8 steps on your sample input string. Demo
This is less strict than Andreas' | based pattern, but takes fewer steps.
It depends on how strict the pattern must be. My pattern will match !==.
If you want to improve your loop method, write a break after you have matched the entire comparison operator.
Actually, you are looping the operators. That would have been their issue (or one of them). Your method will not match ==. I'm not sure if that is a possible comparison (it is not in your list).

Compare two digits elegant solution

I have the following two variables:
$addressphone='5612719999';
$googlephone='561-271-9999';
Is there an elegant solution in PHP that can validate that these two variables actually are equal. I'd prefer not to use str_replace as the conditions can change and I'd have to account for everything.
I've tried casting and intval but neither seemed to work
UPDATE
$addressphone='5612719999';
$googlephone='561-271-9999';
preg_replace("/\D/","",$googlephone);
var_dump($googlephone);
returns string(12) "561-271-9999"
I'm kind of reiterating what the comments say, but you should remove the non-digits from each string and them compare their integer values.
// original, non-integer-infested strings
$addressphone= "5612719999";
$googlephone= "561-271-9999";
// remove non-digits
$addressphone = preg_replace("/\D/","",$addressphone);
$googlephone = preg_replace("/\D/","",$googlephone);
and then you can check the following condition for equality:
// compare integer values of digit-only strings
intval($addressphone) == intval($googlephone)
// should return true
I would use preg_replace() to remove all non-numeric characters. That way, you're just working with numeric strings, which you can compare any way you'd like.
<?php
$testString = "123-456-7890";
echo preg_replace("/\D/", "", $testString); //echos 1234567890
?>
Try this :
print_r($addressphone === implode("", explode("-",$googlephone)))
$pieces = explode("-", $googlephone);
$newstring="";
foeach ($piece in $pieces)
{
$newstring +=piece;
}
Now compare your string with $newstring.
Remove everything that isn't a digit:
<?php
$addressphone ='5612719999';
$googlephone ='561-271-9999';
$number_wang = function($numberish) {
return preg_replace('/[^0-9]/', '', $numberish);
};
assert($number_wang($googlephone) == $addressphone);

How to disable ' - ; : ~ ` from input and remove from string?

I tried to add extra security by removing special characters. I want to allow letters, numbers and ? = & only.
I tried:
if (strpos($_SERVER['REQUEST_URI'],'\'')) { echo 'true'; }
I cannot just simply put ' in between the '' as it breaks it so I tried adding the \ but it didn't work.
Is there a way to detect all the symbols in the url string or input field?
EDIT:
tried adding < simply into the list
if (preg_match('#[#*,!$\'\-;:<>~`^|\(\\)\\{\\}\\[\\]]#i', $_SERVER['REQUEST_URI']) || strpos($_SERVER['REQUEST_URI'],'script')) {
echo 'Cannot do that';
}
I tried adding ([\<])([^\>]{1,})*([\>]) into there but it didn't work.
I also tried adding a condition if strcmp($_SERVER['REQUEST_URI'], strip_tags($_SERVER['REQUEST_URI'])) != 0
and when i added into the url, it didn't do anything
Use preg_match to test for anything but the characters you want:
if (preg_match('#[^a-z0-9?=&]#i', $str)) { echo 'true'; }
Use preg_replace to remove them:
$str = preg_replace('#[^a-z0-9?=&]#i', '', $str);
If you just want to prohibit certain characters, use a regular expression that just matches those characters:
if (preg_match('#[\'\-;:~`]#i', $str)) { echo 'true'; }
You can fix that using double quotes as strings delimiter, try this
if (strpos($_SERVER['REQUEST_URI'],"'")) { echo 'true'; }
One thing that none of the posts addressed is why strpos didn't work for you. strpos can return two types. It can return an integer that is greater than or equal to zero. 0 being the first character. It can also return a boolean type false. To check if if strpos found a match it would have to have been written like this:
if (strpos($_SERVER['REQUEST_URI'],'\'') !== false) { echo 'true'; }
From the PHP Documentation The comparison $a !== $b operator works this way:
return TRUE if $a is not equal to $b, or they are not of the same type.
Information on strpos returning two types (boolean false or an integer) can be found in this PHP strpos Documentation. In particular:
Returns the position of where the needle exists relative to the beginning of the haystack string (independent of offset). Also note that string positions start at 0, and not 1.
Returns FALSE if the needle was not found.
So as you can see 0 and false are not the same thing which is why your test failed.
As for security and strings in PHP I recommend you look at this StackOverflow article for some opinions on the matter.

php string replace by str_replace issue

i made a function to replace a words in a string by putting new words from an array.
this is my code
function myseo($t){
$a = array('me','lord');
$b = array('Mine','TheLord');
$theseotext = $t;
$theseotext = str_replace($a,$b, $theseotext);
return $theseotext;
}
echo myseo('This is me Mrlord');
the output is
This is Mine MrTheLord
and it is wrong it should be print
This is Mine Mrlord
because word (Mrlord) is not included in the array.
i hope i explained my issue in good way. any help guys
regards
According to the code it is correct, but you want it to isolate by word. You could simply do this:
function myseo($t){
$a = array(' me ',' lord ');
$b = array(' Mine ',' TheLord ');
return str_replace($a,$b, ' '.$t.' ');
}
echo myseo('This is me Mrlord');
keep in mind this is kind of a cheap hack since I surround the replace string with empty spaces to ensure both sides get considered. This wouldn't work for punctuated strings. The alternate would be to break apart the string and replace each word individually.
str_replace doesn't look at full words only - it looks at any matching sequence of characters.
Thus, lord matches the latter part of Mrlord.
use str_ireplace instead, it's case insensitive.

PHP - Parse mathematical equations inside strings

I'm struggling to find the best way to do this. Basically I am provided strings that are like this with the task of printing out the string with the math parsed.
Jack has a [0.8*100]% chance of passing the test. Katie has a [(0.25 + 0.1)*100]% chance.
The mathematical equations are always encapsulated by square brackets. Why I'm dealing with strings like this is a long story, but I'd really appreciate the help!
There are plenty of math evaluation libraries for PHP. A quick web search turns up this one.
Writing your own parser is also an option, and if it's just basic arithmetic it shouldn't be too difficult. With the resources out there, I'd stay away from this.
You could take a simpler approach and use eval. Be careful to sanitize your input first. On the eval docs's page, there are comments with code to do that. Here's one example:
Disclaimer: I know eval is just a misspelling of evil, and it's a horrible horrible thing, and all that. If used right, it has uses, though.
<?php
$test = '2+3*pi';
// Remove whitespaces
$test = preg_replace('/\s+/', '', $test);
$number = '(?:\d+(?:[,.]\d+)?|pi|π)'; // What is a number
$functions = '(?:sinh?|cosh?|tanh?|abs|acosh?|asinh?|atanh?|exp|log10|deg2rad|rad2deg|sqrt|ceil|floor|round)'; // Allowed PHP functions
$operators = '[+\/*\^%-]'; // Allowed math operators
$regexp = '/^(('.$number.'|'.$functions.'\s*\((?1)+\)|\((?1)+\))(?:'.$operators.'(?2))?)+$/'; // Final regexp, heavily using recursive patterns
if (preg_match($regexp, $q))
{
$test = preg_replace('!pi|π!', 'pi()', $test); // Replace pi with pi function
eval('$result = '.$test.';');
}
else
{
$result = false;
}
?>
preg_match_all('/\[(.*?)\]/', $string, $out);
foreach ($out[1] as $k => $v)
{
eval("\$result = $v;");
$string = str_replace($out[0][$k], $result, $string);
}
This code is highly dangerous if the strings are user inputs because it allows any arbitrary code to be executed
The eval approach updated from PHP doc examples.
<?php
function calc($equation)
{
// Remove whitespaces
$equation = preg_replace('/\s+/', '', $equation);
echo "$equation\n";
$number = '((?:0|[1-9]\d*)(?:\.\d*)?(?:[eE][+\-]?\d+)?|pi|π)'; // What is a number
$functions = '(?:sinh?|cosh?|tanh?|acosh?|asinh?|atanh?|exp|log(10)?|deg2rad|rad2deg|sqrt|pow|abs|intval|ceil|floor|round|(mt_)?rand|gmp_fact)'; // Allowed PHP functions
$operators = '[\/*\^\+-,]'; // Allowed math operators
$regexp = '/^([+-]?('.$number.'|'.$functions.'\s*\((?1)+\)|\((?1)+\))(?:'.$operators.'(?1))?)+$/'; // Final regexp, heavily using recursive patterns
if (preg_match($regexp, $equation))
{
$equation = preg_replace('!pi|π!', 'pi()', $equation); // Replace pi with pi function
echo "$equation\n";
eval('$result = '.$equation.';');
}
else
{
$result = false;
}
return $result;
}
?>
Sounds, like your homework....but whatever.
You need to use string manipulation php has a lot of built in functions so your in luck. Check out the explode() function for sure and str_split().
Here is a full list of functions specifically related to strings: http://www.w3schools.com/php/php_ref_string.asp
Good Luck.

Categories