'Match single unknown parameter php (Morse-code Regex)
I have an function that checks if string( parameter) matches values in an array and returns an array of possibilities key
function find_possible_match( $criteria ) {
$possible_match = array();
$possibilities = array(
"a"=>".-",
"b"=>"-...",
"c"=>"-.-.",
"d"=>"-..",
"e"=>".",
"f"=>"..-.",
"g"=>"--.",
"h"=>"....",
"i"=>"..",
"j"=>".---",
"k"=>"-.-",
"l"=>".-..",
"m"=>"--",
"n"=>"-.",
"o"=>"---",
"p"=>".--.",
"q"=>"--.-",
"r"=>".-.",
"s"=>"...",
"t"=>"-",
"u"=>"..-",
"v"=>"...-",
"w"=>".--",
"x"=>"-..-",
"y"=>"-.--",
"z"=>"--..",
"0"=>"-----",
"1"=>".----",
"2"=>"..---",
"3"=>"...--",
"4"=>"....-",
"5"=>".....",
"6"=>"-....",
"7"=>"--...",
"8"=>"---..",
"9"=>"----.",
"."=>".-.-.-",
","=>"--..--",
"?"=>"..--..",
"/"=>"-..-.",
" "=>" ");
foreach ( $possibilities as $key => $value ) {
if( $value == $criteria ){
array_push( $possible_match , $key );
}
}
return $possible_match;
}
this is pretty standard is all criteria where string like
find_possible_match( ".-" );
will return [a]... etc
but the twist is that, what if the params has an unknown, example
find_possible_match("?");
should return [e, t], likewise
find_possible_match("?.")
should return ['i','n'] and
find_possible_match(".?")
should return ['i','a']
? in this case is the wildcard. How do i modify the above code to do just that. Thank you
Solution 1:[1]
You could use preg_match()
you check if the $criteria match to $value
. You could replace the $criteria
according to regular expression requirements (escape dot, convert ?
to [.-]
):
function find_possible_match( $criteria ) {
$criteria = str_replace(['.','?'],['\.','[.-]'],$criteria);
$regexp = '~^'.$criteria.'$~';
$possibilities = array(
"a"=>".-",
"b"=>"-...",
"c"=>"-.-.",
"d"=>"-..",
"e"=>".",
"f"=>"..-.",
"g"=>"--.",
"h"=>"....",
"i"=>"..",
"j"=>".---",
"k"=>"-.-",
"l"=>".-..",
"m"=>"--",
"n"=>"-.",
"o"=>"---",
"p"=>".--.",
"q"=>"--.-",
"r"=>".-.",
"s"=>"...",
"t"=>"-",
"u"=>"..-",
"v"=>"...-",
"w"=>".--",
"x"=>"-..-",
"y"=>"-.--",
"z"=>"--..",
"0"=>"-----",
"1"=>".----",
"2"=>"..---",
"3"=>"...--",
"4"=>"....-",
"5"=>".....",
"6"=>"-....",
"7"=>"--...",
"8"=>"---..",
"9"=>"----.",
"."=>".-.-.-",
","=>"--..--",
"?"=>"..--..",
"/"=>"-..-.",
" "=>" ");
$possible_match = array();
foreach ($possibilities as $key => $value) {
if (preg_match($regexp, $value)) {
array_push($possible_match, $key);
}
}
return $possible_match;
}
print_r(find_possible_match(".-")); // ['a']
print_r(find_possible_match("?")); // ['e','t']
print_r(find_possible_match("?.")); // ['i','n']
print_r(find_possible_match(".?")); // ['i','a']
Outputs:
Array
(
[0] => a
)
Array
(
[0] => e
[1] => t
)
Array
(
[0] => i
[1] => n
)
Array
(
[0] => a
[1] => i
)
Solution 2:[2]
You could use array filtering and basic regular expressions to match the $criteria
argument:
<?php
function find_possible_match($criteria)
{
$possible_match = array();
$possibilities = array(
"a" => ".-",
"b" => "-...",
"c" => "-.-.",
"d" => "-..",
"e" => ".",
"f" => "..-.",
"g" => "--.",
"h" => "....",
"i" => "..",
"j" => ".---",
"k" => "-.-",
"l" => ".-..",
"m" => "--",
"n" => "-.",
"o" => "---",
"p" => ".--.",
"q" => "--.-",
"r" => ".-.",
"s" => "...",
"t" => "-",
"u" => "..-",
"v" => "...-",
"w" => ".--",
"x" => "-..-",
"y" => "-.--",
"z" => "--..",
"0" => "-----",
"1" => ".----",
"2" => "..---",
"3" => "...--",
"4" => "....-",
"5" => ".....",
"6" => "-....",
"7" => "--...",
"8" => "---..",
"9" => "----.",
"." => ".-.-.-",
"," => "--..--",
"?" => "..--..",
"/" => "-..-.",
" " => " ",
);
// If the criteria matches a possible morse code (including '.' and '-' only)
if(preg_match('~^[\.-]+$~', $criteria)) {
// Filters the array to match the criteria
$possible_match = array_filter($possibilities, function($value) use ($criteria) {
return $value === $criteria;
});
}
// If the criteria includes a wildcard
else if(preg_match('~[?\.-]~', $criteria)) {
// Creates a regular expression to match according to the given wildcards
// Each ? will match a single . or -
$regex = str_replace('.', '\.', $criteria);
$regex = str_replace('?', '[\.-]', $regex);
$regex = "~^{$regex}$~";
// Filters the array to match the criteria
$possible_match = array_filter($possibilities, function($value) use ($criteria, $regex) {
return preg_match($regex, $value);
});
}
// Return matches
return array_keys($possible_match);
}
// Test cases
$test = array(
'.-',
'?',
'?.',
'.?',
);
foreach($test as $criteria) {
print_r(find_possible_match($criteria));
}
Output:
Array
(
[0] => a
)
Array
(
[0] => e
[1] => t
)
Array
(
[0] => i
[1] => n
)
Array
(
[0] => a
[1] => i
)
Solution 3:[3]
You can do it this way:
function get_morse() {
return $morse_codes = array(
"A"=>".-",
"B"=>"-...",
"C"=>"-.-.",
"D"=>"-..",
"E"=>".",
"F"=>"..-.",
"G"=>"--.",
"H"=>"....",
"I"=>"..",
"J"=>".---",
"K"=>"-.-",
"L"=>".-..",
"M"=>"--",
"N"=>"-.",
"O"=>"---",
"P"=>".--.",
"Q"=>"--.-",
"R"=>".-.",
"S"=>"...",
"T"=>"-",
"U"=>"..-",
"V"=>"...-",
"W"=>".--",
"X"=>"-..-",
"Y"=>"-.--",
"Z"=>"--..",
"0"=>"-----",
"1"=>".----",
"2"=>"..---",
"3"=>"...--",
"4"=>"....-",
"5"=>".....",
"6"=>"-....",
"7"=>"--...",
"8"=>"---..",
"9"=>"----.",
"."=>".-.-.-",
","=>"--..--",
"?"=>"..--..",
"/"=>"-..-.",
" "=>" "
);
}
function possibilities($signals) {
$signals = str_replace(['.','?'],['\.','[.-]'],$signals);
$regexp = '~^'.$signals.'$~';
$morse_codes = get_morse();
$result = [];
foreach ($morse_codes as $key => $value) {
if (preg_match($regexp, $value)) {
$result[$value] = $key;
}
}
krsort($result);
return array_values($result);
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Syscall |
Solution 2 | |
Solution 3 | Kasim Ridwan |