Right to the problem...user need to input text (to be specific the input text is serial number), this input must be compared with database. However because of small print user will make mistake between characters like: (B/8), (1/l),(0,o),(u,v).
The question is how to make the user input "l234B" a valid entry when the serial number is "12348"??
here is another examples: o12u3 ---> 012v3
thanks.
Some solution might be to replace all occorences like "8" by "[8B]" to match against both possibilities:
$sn = "l234B"; $sn_new = "";
$problematic_chars = ['B' => 'B8', '8' => 'B8', '1' => '1l', 'l' => '1l', ...];
// Go through original string and create new string
// "l234B" becomes "[1l]234[8B]"
for($i = 0; $i < strlen($sn); $i++) {
$char = $sn[$i];
if (array_key_exists($char, $problematic_chars)) {
$sn_new .= "[".$problematic_chars[$char]."]";
} else {
$sn_new .= $char;
}
}
// Query stuff
$sql = "SELECT * FROM table_name WHERE sn REGEXP '^${sn_new}\$'";
Did not write PHP for long time, but I think you get the idea.
You may want to try similar_text function rather than using regular expressions and validate only non-ambiguous chars.
// to query
$id = "ABF8...";
// all combinations pre-generated
$c = array(
array('B' => 'B', '8' => '8', ...),
array('B' => 'B', '8' => 'B', ...),
array('B' => '8', '8' => '8', ...),
array('B' => '8', '8' => 'B', ...),
...
);
// generating all versions
foreach($c as $v)
{
$ids[] = strtr($id, $v);
}
the optimal solution depends on your specific setup. but probably you will have the IDs somewhere and you have to query them. so you will have to replace the ambigiuous chars in all possible combinations and query those.
strtr()
Related
I have a query like this:
$content = "How technology is helping to change the way people think about the food on their plate and the food impact for them. Technology could have a role to play in raising awareness of the impact our diets have on the planet.";
$exp = explode(" ", $content)
for($j = 0; $j < count($exp); $j++){
$this->db->query("INSERT INTO news (news_id, news_content) VALUES ('$id', $exp[$j])");
}
But, I don't want to insert all the words, i just need to insert the word that only appear more than once (technology, food, impact). Is it possible to do that? can someone help me?
I would process the text content using array_filter to exclude words that are in a stopword list, then count the occurrences of each word using array_count_values and then array_filter out the words that occur only once. You can then write the remaining words (which will be the keys of the output array) to the database. For example:
$content = "How technology is helping to change the way people think about the food on their plate and the food impact for them. Technology could have a role to play in raising awareness of the impact our diets have on the planet.";
$stopwords = array('how', 'is', 'to', 'the', 'way', 'on', 'and', 'for', 'a', 'in', 'of', 'our', 'have');
// count all words in $content not in the stopwords list
$counts = array_count_values(array_filter(explode(' ', strtolower($content)), function ($w) use ($stopwords) {
return !in_array($w, $stopwords);
}));
// filter out words only seen once
$counts = array_filter($counts, function ($v) { return $v > 1; });
// write those words to the database
foreach ($counts as $key => $value) {
$this->db->query("INSERT INTO news (news_id, news_content) VALUES ('$id', '$key')");
}
For your sample data, the final result in $counts will be:
Array
(
[technology] => 2
[food] => 2
[impact] => 2
)
There are a lot of options here I believe.
Here is my solution(s): You could use search_array() for this. The search array returns false if no other needle is found in_array in an array. If another word is found it returns the key.
Depending of your needs, you could use one of these options below.
//Option 1
//Words that actually appear more than once...
$new_arr = array();
foreach($exp as $key=>$e) {
//Must be this word only (therefore the true-statement
$search = array_search($e, $exp, true);
if ($search !== false && $search != $key) {
$new_arr[] = $e;
}
}
//Option 2
//
//Your question was not totally clear so I add this code as well
//Words with asterixes before and after that appear more than once
$new_arr = array();
foreach($exp as $key=>$e) {
//Two asterixes at the beginning of the sting and two at the end
//strtolower sets **Technology** and **technology** as a duplicate of word
if (substr($e,0,2) == "**" && substr($e,-2,2) == "**") {
$search = array_search(strtolower($e), $exp);
if ($search !== false && $search != $key) {
$new_arr[] = $e;
}
}
}
for($j = 0; $j < count($new_arr); $j++){
$this->db->query("INSERT INTO news (news_id, news_content)
VALUES ('$id', $new_arr[$j])");
}
As someone mentioned in a comment you should prevent SQL injections by typing that way in the INSERT-statement (and you should), but the question was mainly about finding duplicates in a string in do something with them so therefore I won't go further with that comment.
The result array $new_arr would like: (option 1)
array (size=9)
0 => string 'the' (length=3)
1 => string 'the' (length=3)
2 => string '**food**' (length=8)
3 => string 'to' (length=2)
4 => string 'the' (length=3)
5 => string '**impact**' (length=10)
6 => string 'have' (length=4)
7 => string 'on' (length=2)
8 => string 'the' (length=3)
The reason why Technology and technology is not the same because that its an uppercase T in one of the words.
The result array $new_arr would like: (option 2)
array (size=3)
0 => string '**food**' (length=8)
1 => string '**Technology**' (length=14)
2 => string '**impact**' (length=10)
Please help me to solve this issue. I'm not sure is it possible or not! I need a small tricky solution.
<?php include_once"system/hijri_calendar.php";
echo (new hijri\datetime()) -> format ('_j');
?>
Above code gives me an output of integer (1...30) in English.
Now, After echo, I want to change this English language to other languages.
Example:
Say Above code gives me an output 1
I want to change this output (1) to other languages (১)
If I get you right you are trying to get the value from one array based on the value and key from another array. You can use array_search() to find the key from array based on value
<?php
$en = array(1,2,3,4,5,6,7,8,9,0);
$bn = array('১','২','৩','৪','৫','৬','৭','৮','৯','০');
var_dump(array_search(5, $en)); // gives the key 4 from $en where value is 5
// array keys strart with 0
// so you can do
var_dump($bn[array_search(5, $en)]); // gives ৬
PHPFiddle to play with
Quick and dirty:
function __($number, $lang)
{
if ($lang == 'en') {
return $number;
}
$translate = array();
$translate['bn'] = array(
'1' => '১',
'2' => '২',
'3' => '৩',
'4' => '৪',
'5' => '৫',
'6' => '৬',
'7' => '৭',
'8' => '৮',
'9' => '৯',
'0' => '০'
);
$translate['th'] = array(
'1' => '๑',
'2' => '๒',
'3' => '๓',
'4' => '๔',
'5' => '๕',
'6' => '๖',
'7' => '๗',
'8' => '๘',
'9' => '๙',
'0' => '๐'
);
$digits = str_split($number,1);
$return_this = '';
foreach($digits as $digit){
$return_this .= $translate[$lang][$digit];
}
return $return_this;
}
echo __('905','bn');
Break down, if the lang is en you get what you give, if bn or th, it'll break the number apart and rebuild it using the requested array.
This is basically how I do I18n except the arrays for each language are in their own files.
I've changed the arrays slightly to simplify things. If the array is in the order of the digits (so I've moved the 0 element to position 0 in the array) you can use...
$bn = array('০','১','২','৩','৪','৫','৬','৭','৮','৯');
$in = "18";
$out = "";
foreach ( str_split($in) as $ch ) {
$out .= $bn[$ch];
}
echo $out;
I'm trying to get a random array for specific key.
this is my code so far,
$convert = array(
'a' => 'Amusing','Amazing',
'b' => 'Beyond',
'c' => 'Clever','Colorful','Calm',
'd' => 'Dangerous','Donkey',
'e' => 'Endangered',
'f' => 'Fancy',
'g' => 'Great',
'h' => 'Helpful','Humorous',
);
$txt="baca";
$txt=strtolower($txt);
$arr=str_split($txt);
foreach ($arr as $alfa) {
echo $alfa." = ".$convert[$alfa]."\n";
}
the output would be :
b = Beyond
a = Amusing
c = Clever
a = Amusing
but I'm trying to get
b = Beyond
a = Amusing
c = Clever
a = Amazing
Unique value for specific array ('a') in this case.
I tried to use array_rand but failed. I would appreciate any advice given..
This:
array(
'a' => 'Amusing','Amazing',
...
)
is equivalent to:
array(
'a' => 'Amusing',
0 => 'Amazing',
...
)
You're not specifying a key for the word "Amazing", so it automatically gets a numeric key. It does not in any way actually belong to the 'a' key, even if you write it on the same line.
What you want is:
array(
'a' => array('Amusing', 'Amazing'),
...
)
And then:
$values = $convert['a'];
echo $values[array_rand($values)];
I have some inputs that I need to process from a form. The # of inputs from a form depends on the number of languages in my application. For example, lets say I support english and french:
$input = array(
'name_1' => 'Some input in english',
'content_1' => 'Some long text in english',
'name_2' => 'Some input in french',
'content_2' => 'Some long text in french'
);
...Where '1' and '2' are the IDs of english and french respectively. What I want to do is explode the strings:
foreach($input as $key=>$val)
{
$exploded = explode('_', $key);
$arr = $exploded[1];
$key = $exploded[2];
}
..And then push them to separate arrays. Keep in mind that there could be 2 languages, or 10, so just initializing 2 arrays and checking for '1' or '2' as the $key won't work.
How can I push the values of each to an array so that I end up with an array that look something like this?
$results = array( '1' => array('name' => 'Some input in english', 'content' => 'Some long text in english'), '2' => array('name' => 'Some input in french', 'content' => 'Some long text in french');
Thanks in advance. One idea I had was to initialize 2 arrays based off a count of unique key values, but wanted to check first to see if there is a "right" way to do this for a function already there for something like this.
Would something like this work for you?
$results = array();
foreach($input as $key=>$val)
{
$exploded = explode('_', $key);
$results[$exploded[1]][$exploded[0]] = $val;
}
I tried Googling this but not sure what's the best thing to look for. What I am trying to do is to translate a text input to output the letters of a touch tone phone. For example Hello World would output 43550 96153the idea is I'm trying to use the tropo voice api system and want the user to be able to enter their name as touch tone values and match that to their name as numbers in my database.
I'm assuming this can be done with a function along the lines of
$input= $touchtone_value;
$number_two_array (a,b,c);
if( $input==in_array($number_two_array)){
$output = '2';
}
I'm sure this will work. However, if there is a class out there or a simpler function than to break each letter into number arrays I think that would be a better way to do it. At this point this is a fairly open ended question as I have NO IDEA where to start as the best way to accomplish this.
EDIT: I found a solution, not sure it's the best one.
$input = strtolower('HELLO WORLD');
echo 'input: '. $input. "\n";
echo $output = 'output: '. strtr($input,'abcdefghijklmnopqrstuvwxyz', '22233344455566677778889999');
input:hello world
output: 43556 96753
Now I just need to find a way to remove white space :)
http://codepad.org/Ieug0Zuw
Source: code a number into letters
PHP provides a function called strtr which does string translations. The first argument is what you want to translate, the second is the original characters, the third is the replacement characters. Below is a function that should do what you want. Edit: Updated my sample to strip out any characters that aren't supported (anything other than a-z or a space)
<?php
function get_tones($inp) {
$from = 'abcdefghijklmnopqrstuvwxyz ';
$to = '222333444555666777788899990';
// convert the input to lower case
$inp = strtolower($inp);
// remove anything that isn't a letter or a space
$inp = preg_replace('/[^a-z ]/', '', $inp);
return strtr($inp, $from, $to);
}
assert(get_tones('Hello world') == '43556096753');
assert(get_tones('Hell234"*&o world') == '43556096753');
assert(get_tones('ALEX') == '2539');
assert(get_tones(' ') == '0000');
How about a structure like this... NOTE: This will ignore invalid 'letters' like spaces, punctuation, etc..
LIVE DEMO http://codepad.org/pQHGhm7Y
<?php
echo getNumbersFromText('Hello There').'<br />';
echo getNumbersFromText('This is a really long text string').'<br />';
function getNumbersFromText($inp){
$result=array();
$inp = strtolower($inp);
$keypad = array('a' => '2', 'b' => '2', 'c' => '2', 'd' => '3',
'e' => '3', 'f' => '3', 'g' => '4', 'h' => '4',
'i' => '4', 'j' => '5', 'k' => '5', 'l' => '5',
'm' => '6', 'n' => '6', 'o' => '6', 'p' => '7',
'q' => '7', 'r' => '7', 's' => '7', 't' => '8',
'u' => '8', 'v' => '8', 'w' => '9', 'x' => '9',
'y' => '9', 'z' => '9');
for ($x=0; $x<strlen($inp); $x++){
$letter = $inp[$x];
if ($keypad[$letter]) $result[]= $keypad[$letter];
}
return implode('',$result);
}
?>
I'm not sure I understand exactly what you are asking:
Your input is words, and you want to output the corresponding numbers?
Your input is numbers, and you want to output the corresponding words?
In case (1), it's simple, just use an array that maps each letter of the alphabet to the corresponding numbers (i.e. key is letter, value is number). You can then just iterate over the characters of the input, and output using the corresponding element in the array.
Case (2) is a bit trickier. You can build a Trie from your list of names, and use it to do the lookup.