How to remove accent from characters? (Leave only English alphabet glyphs) - php

I need to transform in PHP, a special character like ă -> a, â -> a, ț -> t and so on.
I need this especially for links, so any help would be appreciated.

When i want to get plain text (from utf-8) i'm using iconv.
iconv('utf8', 'ascii//TRANSLIT', $text);
If it's only for your url, urlencode may be a better idea.

Update the answer from Orlando, I add some more special char
function clean_special_chars ($s, $d=false) {
if($d) $s = utf8_decode( $s );
$chars = array(
'_' => '/`|´|\^|~|¨|ª|º|©|®/',
'a' => '/à|á|ả|ạ|ã|â|ầ|ấ|ẩ|ậ|ẫ|ă|ằ|ắ|ẳ|ặ|ẵ|ä|å|æ/',
'd' => '/đ/',
'e' => '/è|é|ẻ|ẹ|ẽ|ê|ề|ế|ể|ệ|ễ|ë/',
'i' => '/ì|í|ỉ|ị|ĩ|î|ï/',
'o' => '/ò|ó|ỏ|ọ|õ|ô|ồ|ố|ổ|ộ|ỗ|ö|ø/',
'u' => '/ù|ú|û|ũ|ü|ů|ủ|ụ|ư|ứ|ừ|ữ|ử|ự/',
'A' => '/À|Á|Ả|Ạ|Ã|Â|Ầ|Ấ|Ẩ|Ậ|Ẫ|Ă|Ằ|Ắ|Ẳ|Ặ|Ẵ|Ä|Å|Æ/',
'D' => '/Đ/',
'E' => '/È|É|Ẻ|Ẹ|Ẽ|Ê|Ề|Ế|Ể|Ệ|Ễ|Ê|Ë/',
'I' => '/Ì|Í|Ỉ|Ị|Ĩ|Î|Ï/',
'O' => '/Ò|Ó|Ỏ|Ọ|Õ|Ô|Ồ|Ố|Ổ|Ộ|Ỗ|Ö|Ø/',
'U' => '/Ù|Ú|Û|Ũ|Ü|Ů|Ủ|Ụ|Ư|Ứ|Ừ|Ữ|Ử|Ự/',
'c' => '/ć|ĉ|ç/',
'C' => '/Ć|Ĉ|Ç/',
'n' => '/ñ/',
'N' => '/Ñ/',
'y' => '/ý|ỳ|ỷ|ỵ|ỹ|ŷ|ÿ/',
'Y' => '/Ý|Ỳ|Ỷ|Ỵ|Ỹ|Ŷ|Ÿ/'
);
return preg_replace( $chars, array_keys( $chars ), $s );
}

You can use this:
function clean_special_chars( $s, $d=false )
{
if($d) $s = utf8_decode( $s );
$chars = array(
'_' => '/`|´|\^|~|¨|ª|º|©|®/',
'a' => '/à|á|â|ã|ä|å|æ/',
'e' => '/è|é|ê|ë/',
'i' => '/ì|í|î|ĩ|ï/',
'o' => '/ò|ó|ô|õ|ö|ø/',
'u' => '/ù|ú|û|ű|ü|ů/',
'A' => '/À|Á|Â|Ã|Ä|Å|Æ/',
'E' => '/È|É|Ê|Ë/',
'I' => '/Ì|Í|Î|Ĩ|Ï/',
'O' => '/Ò|Ó|Ô|Õ|Ö|Ø/',
'U' => '/Ù|Ú|Û|Ũ|Ü|Ů/',
'c' => '/ć|ĉ|ç/',
'C' => '/Ć|Ĉ|Ç/',
'n' => '/ñ/',
'N' => '/Ñ/',
'y' => '/ý|ŷ|ÿ/',
'Y' => '/Ý|Ŷ|Ÿ/'
);
return preg_replace( $chars, array_keys( $chars ), $s );
}

Related

str_replace exact match only

Good Day,
I am trying to create a morse code to text and text to morse code converter.
My code:
$letter = str_split(strtolower($_POST['text']));
$morse = $_POST['morse'];
$morsecmp = explode(" ",$morse);
$letter = implode(" ",$letter);
$mode = $_POST['sub'];
$morsecode = array(".-","-...","-.-.","-..","..-.","--.","....","..",".---","-.-",".-..","--","-.","---",
".--.","--.-",".-.","...","-.","..-","...-",".--","-..-","-.--","--..",".");
$letters = array("a","b","c","d","f","g","h","i","j","k","l","m","n","o","p","q","r",
"s","t","u","v","w","x","y","z","e");
if($mode == "Text to Morse Code"){
$letter = str_replace($letters,$morsecode,$letter);
$translated = $letter;
}else{
for($x=0;$x<sizeof($letters);$x++){
for($y=0;$y<sizeof($morsecmp);$y++){
if($morsecode[$x] === $morsecmp[$y]){
echo $morsecode[$x]." === ".$letters[$x]."<br>";
$morse = str_replace($morsecode[$x],$letters[$x],$morse);
}
}
}
$translated = $morse;
}
sample input:
.... . .-.. .-.. --- .-- --- .-. .-.. -..
sample output:
h e ed ed o w o r ed d
expected output:
hello wolrd
My problem is that when converting from morse code to text some characters are not captured properly due to str_replace limit where it will replace all string that is similar to the needle, so if i have to replace all "." to e it will also change "...." which should be actually an h.
any help on this would be greatly appreciated.
Thank You.
Just when you repalce the characters add an extra space for the search string.
$morse = $_POST['morse']." "; // this is to add an extra space at the end of the morse string.
Now we replace all occurrences of morse code strings followed by space with the desired letter.
$morse = str_replace($morsecode[$x]." ",$letters[$x],$morse);
First off, you don't have the full alphabet stored in your array. I noticed you're missing 'e'.
Blow the morse code into an array with explode(' ', $morse_code) and then do a replace on the array (use '/' to delimit words).
Condense it back to a string with implode().
heres an array for you to use, its got the whole alphabet (you can use array_flip to switch the keys and values for translating back and forth)
$translator_table = 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' => '----.',
'.' => '.-.-.-',
',' => '--..--',
'?' => '..--.',
);
The only way to replace exact matches is:
$morse = preg_replace("#{$morsecode[$x]}#", $letters[$x], $morse, 1); //Limit to 1

Reverse array values while keeping keys

Here is an array I have:
$a = array('a' => 'a1', 'b' => 'a2', 'c' => 'a3', 'd' => 'a4', 'e' => 'a5');
What I would like to do is reverse the values of the array while keeping the keys intact, in other words it should look like this:
$a = array('a' => 'a5', 'b' => 'a4', 'c' => 'a3', 'd' => 'a2', 'e' => 'a1');
How should I go about it?
P.S. I tried using array_reverse() but it didn't seem to work
Some step-by-step processing using native PHP functions (this can be compressed with less variables):
$a = array('a' => 'a1', 'b' => 'a2', 'c' => 'a3', 'd' => 'a4', 'e' => 'a5');
$k = array_keys($a);
$v = array_values($a);
$rv = array_reverse($v);
$b = array_combine($k, $rv);
var_dump($b);
Result:
array(5) {
'a' =>
string(2) "a5"
'b' =>
string(2) "a4"
'c' =>
string(2) "a3"
'd' =>
string(2) "a2"
'e' =>
string(2) "a1"
}
It is possible by using array_combine, array_values, array_keys and array_values. May seem like an awful lot of functions for a simple task, and there may be easier ways though.
array_combine( array_keys( $a ), array_reverse( array_values( $a ) ) );
Here another way;
$keys = array_keys($a);
$vals = array_reverse(array_values($a));
foreach ($vals as $k => $v) $a[$keys[$k]] = $v;
I think this should work..
<?php
$old = array('a' => 'a1', 'b' => 'a2', 'c' => 'a3', 'd' => 'a4', 'e' => 'a5');
$rev = array_reverse($old);
foreach ($old as $key => $value) {
$new[$key] = current($rev);
next($rev);
}
print_r($new);
?>
This'll do it (just wrote it, demo here):
<?php
function value_reverse($array)
{
$keys = array_keys($array);
$reversed_values = array_reverse(array_values($array), true);
return array_combine($keys, $reversed_values);
}
$a = array('a' => 'a1', 'b' => 'a2', 'c' => 'a3', 'd' => 'a4', 'e' => 'a5');
print_r( value_reverse($a) );

Is there a cleaner way to filter by key's value?

$a = array(
0 => array( 'one' => 1, 'two' => 2 ),
1 => array( 'one' => 3, 'two' => 4 ),
2 => array( 'one' => 5, 'two' => 2 )
);
$c = count( $a );
$r = array();
for ( $i = 0; $i < $c; $i++ )
{
if ( $a[$i]['two'] == 2 )
$r[] = $a[$i];
}
Is there a cleaner way then to do all of the above?
Have you tried using array_filter()?
$r = array_filter($a, function($var) {
return ($var['two'] === 2);
});
The output of the above is slightly different than your original code:
Yours:
array(
0 => array('one' => 1, 'two' => 2),
1 => array('one' => 5, 'two' => 2)
)
Using array_filter:
array(
0 => array('one' => 1, 'two' => 2),
2 => array('one' => 5, 'two' => 2) // Note the key is 2, not 1
)
If you need the keys collapsed, you can follow up the array_filter() with array_values() or array_multisort()
You could write a function to do just this and then use array_walk or array_filter but that's about it.
Only way I can see to clean it up more would be to change the original datastructure.

Make str_replace not replace a letter if follows another letter

I have a string which contains a math formula, like T + ST + s + t ...
I'm replacing all those letter identifiers with numbers using:
$ids = array(
'T' => $t1,
'ST', => $st,
's', => $s1,
't', => $t2,
'N', => 1,
);
foreach ($ids as $id => $value) {
if (strpos($formula, $id) !== false) {
$formula = str_replace($id, $value, $formula);
}
}
Which is ok in certain situations.
But if the formula has ST at the beginning I get a string like S345324 ..
I fixed this by moving ST in the first position in my array, but I feel it's not really the best option :)
Are there any other "nicer" solutions?
Are you looking for strtr()?
$ids = array(
'T' => $t1,
'ST' => $st,
's' => $s1,
't' => $t2,
'N' => 1,
);
$formula = strtr($formula, $ids);
Note that since strtr() always tries to find the longest possible match, it won't replace occurrences of ST with S$t1 (instead of $st), regardless of how your $replace_pairs array is ordered.
Example (as seen on codepad):
$ids = array(
'T' => 10,
'ST' => 20,
's' => 30,
't' => 40,
'N' => 1,
);
$formula = 'T + ST + s + t';
echo strtr($formula, $ids);
Prints:
10 + 20 + 30 + 40

Output an array as PHP eval-able code

Basically I want some function like array_as_php which is essentially the inverse of eval:
$array = array( '1' => 'b', '2' => 'c' );
echo array_as_php($array);
will print the following eval-able string:
array( '1' => 'b', '2' => 'c' )
var_export() is what you are looking for.
$array = array ('1' => 'b', '2' => 'c' );
echo var_export($array, true);

Categories