Changing string names from a list - php

Doing this in PHP
I have users input an abbreviation for a city, that gets saved as a string, for example:
ANA
BOS
VAN
These stand for: Anaheim Boston Vancouver
I want it so that when I get the input/string, it changes the string name to it's full name.
ANA -> Anaheim
BOS -> Boston
VAN -> Vancouver
What is the best way to go about this? Thank you all, greatly appreciated.

Peut22's answer ist working, but i think it is better to store the pairs in an array to be more eaily maintainable. You could also get this array from a database or config file.
$names = array(
"ANA" => "Anaheim",
"BOS" => "Boston",
"VAN" => "Vancouver",
);
if(array_key_exists((string)$userinput, $names)) {
echo $names[$userinput];
} else {
echo "invalid";
}

update: fixed, so there is no "undefined index" - notice in case you got such a low error_reportinglevel set:
$names["ANA"] = "Anaheim";
$names["BOS"] = "Boston";
$names["VAN"] = "Vancouver";
function getFullName($input, $names)
{
//turning all input into upper case letters:
$input = strtoupper($input);
//making sure input is maximum 3 characters long:
$input = substr($input, 0, 3);
if(!array_key_exists($input, $names))
{
return "*ERROR: Unknown City Abbreviation*";
}
else
{
return $names[$input];
}
}
//usage:
$user_input = "bos";
echo getFullName($user_input, $names);

I think you would get a good result by using a switch, which returns the full name if you happend to get an abbreviation, of the full input string if the name is not recognized.
An example in pseudo code would be:
Switch string
case "ANA" : string = "Anaheim"
case "BOS" : string = "boston"
end
EDIT: if you're using php, the code would then look like :
switch ($i) {
case "ANA":
$i="anaheim"
break;
case "BOS":
$i="boston"
break;
}

Related

Using regex to select AFTER one line all the way to a specific word on another line

I'm not sure if this is possible. I have a list with specific words on new lines, and I need to select the words between those lines. For example my source is:
Word_1
Word_2
Location
Variable_1
Variable_2
Variable_3
Section
Word_9
I need regex to find the line after Location, which I am doing using (.*(?<=\bLocation\s)(\w+).*)|.* and replacing with $1. However this only gives me Variable_1 and I need it to give me Variable_1,Variable_2,Variable_3. And here's the catch, sometimes there is one Variable, sometimes 2, sometimes 3, sometimes 4. BUT, the following word will always be Section. So I'm thinking I need basically some way to tell Regex to select every line after Location but before Section.
Any ideas?
Real world example:
Category
Business
Dates
StatusOpen
Closing Information
Location
National
South-East Asia
New South Wales
Victoria
Sections
General
Difficulty Rating
Administrator
Output would be National,South-East Asia,New South Wales,Victoria
In Python you can use DOTALL in your re.
print(re.findall("Location(.*)Section",string,re.DOTALL)[0])
Output:
Variable_1
Variable_2
Variable_3
For PHP can you try the below.
'\w*Location(.*)Section/s'
You can check the output in this link for your example.
Regex101 link
Output match:
National
South-East Asia
New South Wales
Victoria
A solution with PHP would be:
<?php
$string =
"Category
Business
Dates
StatusOpen
Closing Information
Location
National
South-East Asia
New South Wales
Victoria
Sections
General
Difficulty Rating
Administrator";
$initialValue = false;
$lastValue = false;
$arResult = [];
$arValue = explode("\n", $string);
foreach($arValue as $value) {
$value = trim($value);
if ($value == "Location") {
$initialValue = true;
} else if ($value == "Sections") {
$lastValue = true;
} else if ($initialValue == true && $lastValue == false) {
$arResult[] = $value;
}
}
echo implode(",",$arResult); // National,South-East Asia,New South Wales,Victoria

Regular expression for determining specific characteristics of a string (that is a poker hand)

I have a string in the form of "AsKcQsJd" that represents 4 cards from a deck of playing cards. The uppercase value represnts the card value (in this case, Ace, King, Queen, and Jack) and the lowercase value represents the suit (in this case, spade, club, spade, diamond).
Say I have another value that tells me what suit I'm looking for. So in this case, I have:
$hand = 'AsKcQsJd';
$suit = 's';
How can I write a regular expression that checks if the hand has an Ace in it, followed by the suit, so in this case 'As' and also any other card that has the suit? Or in 'poker terms', I'm trying to determine if the hand has the 'ace high flush draw' for the suit defined as $suit.
To further explain, I need to check if any combination of the following two cards exist:
AsKs, AsQs, AsJs, AsTs,As9s,As8s,As7s,As6s,As5s,As4s,As3s,As2s
With the added complexity that these cards could occur anywhere in the hand. For example, the string could have As at the front and Ks at the end. That's why I think a regular expression is the best method for determining if the two coexist in the string.
You might use two lookaheads, one for As, and one for [^A]s, like this:
(?=.*As)(?=.*[^A]s)
https://regex101.com/r/8hkWTv/1
$suit = 's';
$re = '/(?=.*A' . $suit . ')(?=.*[^A]' . $suit . ')/';
print($re); // /(?=.*As)(?=.*[^A]s)/
print(preg_match($re, 'AsKcQsJd')); // 1
print(preg_match($re, 'AdKcQsJd')); // 0
print(preg_match($re, 'KsKcQsJd')); // 0
I'm not sure regex is the best solution but if that's your cup of tea you can do it pretty easily with alternation like this:
As.*s|s.*As
Or better yet - to capture the actual cards giving you a match:
(As).*(.s)|(.s).*(As)
These basically say - the hand has a spade followed by an ace of spades OR has ace of spades followed by any other spade. https://regex101.com/r/pdwHPQ/1
That said, I'd probably consider building a simple class to parse the hand and give you more flexibility when it comes to answering questions about what cards are present. Whether or not this is worth it really depends a lot on your app. Here's an idea:
$hand = 'AsKh4c5c9h2s';
$cards = new Cards($hand);
$spades = $cards->getCardsBySuit('s');
if (in_array('As',array_keys($spades)) && count($spades) > 1) {
// hand has ace high flush draw
echo 'yep';
}
class Cards {
private $cards = '';
public function __construct($hand) {
foreach (str_split($hand,2) as $card) {
$this->cards[$card] = [
'rank' => substr($card,0,1),
'suit' => substr($card,1,1)
];
}
}
public function getCardsBySuit($suit) {
$response = [];
foreach ($this->cards as $k => $card) {
if ($card['suit'] == $suit) {
$response[$k] = $card;
}
}
return $response;
}
}

Check / match string against partial strings in array

I am trying to match a full UK postcode against a partial postcode.
Take a users postcode, i.e g22 1pf, and see if there's a match / partial match in the array / database.
//Sample data
$postcode_to_check= 'g401pf';
//$postcode_to_check= 'g651qr';
//$postcode_to_check= 'g51rq';
//$postcode_to_check= 'g659rs';
//$postcode_to_check= 'g40';
$postcodes = array('g657','g658','g659','g659pf','g40','g5');
$counter=0;
foreach($postcodes as $postcode){
$postcode_data[] = array('id' =>$counter++ , 'postcode' => $postcode, 'charge' => '20.00');
}
I do have some code but that was just comparing the strings with fixed lengths from the database. I need the strings in the array / database to be dynamic in length.
The database may contain "g22" this would be a match, it could also contain more or less of the postcode, i.e "g221" or "g221p" which would also be a match. It could contain "g221q" or "g221qr" these would not match.
Help Appreciated, Thank you
edit.
I was possibly overthinking this. the following pseudo code seems to function as expected.
check_delivery('g401pf');
//this would match because g40 is in the database.
check_delivery('g651dt');
// g651dt this would NOT match because g651dt is not in the database.
check_delivery('g524pq');
//g524pq this would match because g5 is in the database.
check_delivery('g659pf');
//g659pf this would match because g659 is in the database.
check_delivery('g655pf');
//g655pf this would not match, g665 is not in the database
//expected output, 3 matches
function check_delivery($postcode_to_check){
$postcodes = array('g657','g658','g659','g659pf','g40','g5');
$counter=0;
foreach($postcodes as $postcode){
$stripped_postcode = substr($postcode_to_check,0, strlen($postcode));
if($postcode==$stripped_postcode){
echo "Matched<br><br>";
break;
}
}
}
<?php
$postcode_to_check= 'g401pf';
$arr = preg_split("/\d+/",$postcode_to_check,-1, PREG_SPLIT_NO_EMPTY);
preg_match_all('/\d+/', $postcode_to_check, $postcode);
$out = implode("",array_map(function($postcode) {return implode("",$postcode);},$postcode));
$first_char = mb_substr($arr[1], 0, 1);
$MatchingPostcode=$arr[0].''.$out.''.$first_char;
echo $MatchingPostcode;
SELECT * FROM my_table WHERE column_name LIKE '%$MatchingPostcode%';
It's a dirty solution but it will solve your problem. Things like this should be handled in front-end or in the DB but if you must do it in php then this is a solution.
So this code will match you anything that includes g401p. If you don't want to match in the start of the end just remove % from which part you don't want to match. In my the case i provide you it will search for every column record that has g401p
Check the length and strip the one you want to compare it with to the same length.
function check_delivery($postcode_to_check){
$postcodes = array('g657','g658','g659','g659pf','g40','g5');
$counter=0;
foreach($postcodes as $postcode){
$stripped_postcode = substr($postcode_to_check,0, strlen($postcode));
if($postcode==$stripped_postcode){
echo "Matched<br><br>";
break;
}
}
}

php: find variable characters in an array

Got a varibale that holds phone number and the number have it country prefix before it and the phone number is dynamic and can be any phone number from any country.
So, I need to get the country of the phone number by matching certain characters (i.e the country prefix preceding the phone number) in the variable against the record in the DB (country prefix would be fetched into an array) holding all country prefix.
Sample:
$phoneVar = '4477809098888'; // uk - 44
$phoneVar = '15068094490'; // usa - 1
$phoneVar = '353669767954'; // ireland - 352
$phoneVar = '2348020098787'; // nigeria - 234
If the $phoneVar is assigned any phone number value, need to be able to get the country prefix out of it.
Something like this:
echo getCountryPrefix($phoneVar, $countries_prefix_array);
This would have been easy to achieve using substr
// $countryPrefix = substr($phoneVar, 0, 3);
But countries do not have the same prefix length.
Would be pleased to get help with this.
Something like this will work.
It's probably not accurate to your code, but I'm sure you can see the logic.
function findCountryCode($number, $country_codes) {
$country_codes = usort($country_codes, 'lsort');
foreach ($country_codes as $key => $val) {
if (substr($number, 0, strlen($val)) == $val)
return $key;
}
return false;
}
function lsort($a,$b) {
return strlen($b)-strlen($a);
}
Ok this is a perfect example for a state machine !
simplest way:
$prefixes = array('44' => 'UK', '1' => 'USA', '352' => 'IRELAND', '234' => 'NIGERIA');
preg_match('/^('.implode('|',array_keys($prefixes)).')/', $phoneVar, $matches);
echo $prefixes[$matches[0]];
You might find this schema useful.
The coding is straight-forward, if you maintain a map of prefix to country code.
Sort the prefixes, start at the back so 123 is tried before 1.
You can do this like following codes:
$phoneVar = '4477809098888'; // uk - 44
$county_list = array('uk' => 44, 'usa' => 1, 'ireland' => 352, 'nigeria' => 234);
foreach ($county_list as $key => $value)
{
if (preg_match('/^'.$value.'/', $phoneVar))
{
echo "Country is: ".$key;
echo "Country code: ".$value;
break;
}
}
Output
Country is: uk
Country code: 44
You can use preg_match() :
$phoneVar = "abcdef";
$pattern = '/^44/';
preg_match($pattern, $phoneVar, $matches, PREG_OFFSET_CAPTURE, 3);
print_r("UK : ".$matches);
This can mean lengthy code. But if its just 4 countries then this would serve your purpose.

Replace string within parenthesis with column data

I have written some code to allow calculations to be done on specific columns of data.
For example {1}*{2} would result in column 1 being multiplied by column 2. What I need to be able to do is replace these numbers with the actual values of the column.
Putting it simply I need to be able to get the value within the parenthesis, then use it like $column["value from parenthesis"] to get the value to insert into the calculation.
I can then evaluate the string.
Thanks in advance
Something like this should work:
$myString = '{1}*{2}';
$myValues = [1 => '684', 2 => '42'];
$myFormula = preg_replace_callback('{([0-9]+)}', function($match) use ($myValues) {
return $myValues[$match] ?: 'undefined';
}, $myString);
echo "Resulting formula: $myFormula";
Might want to give a harder error when an undefined index is used, but essentially this should work with some tweaking.
Also if you run a older PHP version than 5.4 you would need to rewrite the short array syntax and the lambda.
PHP Rocks !!!
$string = 'blabla bla I want this to be done !!! {10} + {12} Ah the result is awesome but let\'s try something else {32} * {54}';
// Requires PHP 5.3+
$string = preg_replace_callback('/\{(\d+(\.\d+)?)\}\s*([\+\*\/-])\s*\{(\d+(\.\d+)?)\}/', function($m){
return mathOp($m[3], $m[1], $m[4]);
}, $string);
echo $string; // blabla bla I want this to be done !!! 22 Ah the result is awesome but let's try something else 1728
// function from: http://stackoverflow.com/a/15434232
function mathOp($operator, $n1, $n2){
if(!is_numeric($n1) || !is_numeric($n2)){
return 'Error: You must use numbers';
}
switch($operator){
case '+':
return($n1 + $n2);
case '-':
return($n1 - $n2);
case '*':
return($n1 * $n2);
case '/':
if($n2 == 0){
return 'Error: Division by zero';
}else{
return($n1 / $n2);
}
default:
return 'Unknown Operator detected';
}
}
Online demo.

Categories