Could anyone please help me with the regex of reversing each word in a string?
Sample input:
Hello how are you my friend?
Desired Output
olleH woh era uoy ym ?dneirf
I want to implement this in PHP.
This gives you almost what you want.
If it isn't close enough, look into Blender's solution of exploding on spaces.
preg_replace_callback('/\b(\w+)\b/', function($match) {
return strrev($match[1]);
}, $str);
CodePad.
You can reverse text using plain regex (and some string functions) but it is ugly...
$length = strlen($str);
echo preg_replace(
'/' . str_repeat('(.)', $length) . '/s',
'$' . join('$', range($length, 1)),
$str
);
CodePad.
The code sample above is for demonstration only. Please do not ever use it :)
That can't be done in pure regex, sorry.
Here's a possibly-working PHP script:
$exploded = explode(' ', $string);
$temp = array();
for ($i = 0; $i < count(exploded); $i++) {
$temp[] = strrev(exploded[i]);
}
$temp = implode(' ', $temp);
Not Regex, but this works:
<?php
function reverseWords($text) {
$words = explode(' ', $text);
$c_words = count($words);
$outtext = "";
for ($i = 0; $i < $c_words; $i++) {
if ($i !== 0) $outtext .= " ";
$length = strlen($words[$i]);
for ($p = $length-1; $p >= 0; $p--) {
$outtext .= substr($words[$i], $p, 1);
$start--;
}
}
return $outtext;
}
echo reverseWords("This is a test.");
?>
https://ideone.com/WUtzJ
Now, I forgot about strrev(), so that would shorten it a bit.
EDIT
Using strrev():
<?php
function reverseWords($text) {
$words = explode(' ', $text);
$c_words = count($words);
$outtext = "";
for ($i = 0; $i < $c_words; $i++) {
if ($i !== 0) $outtext .= " ";
$outtext .= strrev($words[$i]);
}
return $outtext;
}
echo reverseWords("This is a test.");
?>
https://ideone.com/NT7A5
This is extremely trivial to accomplish without a regular expression, and I see a lot of massive solutions here, so I thought I'd post a one-liner:
$rev = implode(' ', array_map('strrev', explode(' ', $string)));
Related
My code so far:
$text = 'Herman Archer LIVEs in neW YORK';
$oldWords = explode(' ', $text);
$newWords = array();
$counter = 0;
foreach ($oldWords as $word) {
for($k=0;$k<strlen($word);$k++)
$counter = 0;
if ($word[k] == strtoupper($word[$k]))
$counter=$counter+1;
if($counter>1)
$word = strtolower($word);
if($counter == 1)
$word = ucfirst(strtolower($word));
else $word = strtolower($word);
echo $word."<br>";
}
Result:
Herman
Archer
Lives
In
New
York
Expected output:
Herman Archer lives in new york
If you want to use the counter approach you could use something as the following
<?php
$text = 'Herman Archer LIVEs in A neW YORK';
$words = explode(' ', $text);
foreach($words as &$word) {
$counter = 0;
for($i = 1; $i <= strlen($word);$i++) {
if (strtoupper($word[$i]) == $word[$i]) $counter++;
if ($counter == 2) break;
}
if ($counter == 2) $word = strtolower($word);
}
echo implode(' ', $words);
Let's do it in a simple manner. Let's loop $oldWords, compare the strings from the second character to the end with their lower-case version and replace if the result is different.
for ($index = 0; $index < count($oldWords); $index++) {
//Skip one-lettered words, such as a or A
if (strlen($oldWords[$index]) > 1) {
$lower = strtolower($oldWords[$index]);
if (substr($oldWords[$index], 1) !== substr($lower, 1)) {
$oldWords[$index] = $lower;
}
}
}
If you are using not only English language, you might want to switch to mb_strtolower
<?php
$text = 'Herman Archer LIVEs in neW YORK';
function normalizeText($text)
{
$words = explode(" ", $text);
$normalizedWords = array_map(function ($word) {
$loweredWord = strtolower($word);
if (ucfirst($loweredWord) === $word) {
return $word;
}
return $loweredWord;
}, $words);
return join(" ", $normalizedWords);
}
echo normalizeText($text) . PHP_EOL; // Herman Archer lives in new york
you can combine ctype_upper for first character and ctype_lower for the rest
$text = 'Herman Archer LIVEs in neW YORK';
$oldWords = explode(' ', $text);
$newWords = '';
foreach ($oldWords as $word) {
if(ctype_upper($word[0])&&ctype_lower(substr($word,1))){
$newWords .= $word.' ';
}else{
$newWords .= strtolower($word).' ';
}
}
echo $newWords;
Meanwhile I've found out that this can be done in an easier way
if(isset($_POST["sumbit"])){
$string = $_POST["string"];
if(!empty($string)){
$word = explode (" ",$string);
foreach($words as $word){
//cut the first letter.
//check caselower.
//if not, attach the letter back and turn all lowercase.
//if yes, attach the letter back and leave it .
$wordCut = substr($word,1);
if(ctype_lower($wordCut)){
echo $word." ";
} else {
echo strtolower($word). " ";
}
}
<?php
function pfilter($text){
$result = "";
$word = "";
$length = strlen($text);
$file = fopen("words.txt", "r"); //contents of txt: cat dog (both on new lines)
for($i = 0; $i < $length; $i++){
$result .= $text[$i];
if($text[$i]!=' ') $word .= $text[$i];
if(($text[$i] == ' ' || $i == $length-1) && $word!=' ' && $word!=''){
while(!feof($file)){
$line = str_replace(array("\n", "\r"), '', fgets($file));
if($line == $word){
$wlength = strlen($word);
$rlength = strlen($result);
for($j=1;$j<=$wlength;$j++){
$result[$rlength - $j - 1] = '*';
}
}
}
$word = '';
}
}
fclose($file);
return $result;
}
echo pfilter("cat dog meow bark");
?>
Yes I know there is potentially a one liner that could do all of this. But I'm just confused as to why this isn't working, it should replace both cat and dog with ***, but only does cat in the beginning. There must be something I'm just not seeing here? $line and $word wont match up after the first word, but i've checked and they don't contain spaces
I need to edit all odd words to upper case.
Here is sample of imput string:
very long string with many words
Expected output:
VERY long STRING with MANY words
I have this code, but it seams to me, that I can do it in better way.
<?php
$lines = file($_FILES["fname"]["tmp_name"]);
$pattern = "/(\S[\w]*)/";
foreach($lines as $value)
{
$words = NULL;
$fin_str = NULL;
preg_match_all($pattern, $value, $matches);
for($i = 0; $i < count($matches[0]); $i = $i + 2){
$matches[0][$i] = strtoupper($matches[0][$i]);
$fin_str = implode(" ", $matches[0]);
}
echo $fin_str ."<br>";
P.S. I need to use only preg_match function.
Here's a preg_replace_callback example:
<?php
$str = 'very long string with many words';
$newStr = preg_replace_callback('/([^ ]+) +([^ ]+)/',
function($matches) {
return strtoupper($matches[1]) . ' ' . $matches[2];
}, $str);
print $newStr;
// VERY long STRING with MANY words
?>
You only need to match the repeating pattern: /([^ ]+) +([^ ]+)/, a pair of words, then preg_replace_callback recurses over the string until all possible matches are matched and replaced. preg_replace_callback is necessary to call the strtoupper function and pass the captured backreference to it.
Demo
If you have to use regular expressions, this should get you started:
$input = 'very long string with many words';
if (preg_match_all('/\s*(\S+)\s*(\S+)/', $input, $matches)) {
$words = array();
foreach ($matches[1] as $key => $odd) {
$even = isset($matches[2][$key]) ? $matches[2][$key] : null;
$words[] = strtoupper($odd);
if ($even) {
$words[] = $even;
}
}
echo implode(' ', $words);
}
This will output:
VERY long STRING with MANY words
You may don't need regex simply use explode and concatenate the string again:
<?php
function upperizeEvenWords($str){
$out = "";
$arr = explode(' ', $str);
for ($i = 0; $i < count($arr); $i++){
if (!($i%2)){
$out .= strtoupper($arr[$i])." ";
}
else{
$out .= $arr[$i]." ";
}
}
return trim($out);
}
$str = "very long string with many words";
echo upperizeEvenWords($str);
Checkout this DEMO
I have this code:
$text= "#h #gg #مصر";
$get_hash = preg_match_all("/(^|\s)#(\w*[a-zA-Z-أ-إ-آ-ا-ب-ت-ث-ج-ح-خ-د-ذ-ر-ز-س-ش-ص-ض-ط-ظ-ع-غ-ف-ق-ك-ل-م-ن-ه-و-لا-لا-لآ-لأ-لإ-ى-ي-ئ-ة-ء-ؤ_]+\w*)/", $text, $matches);
$array_hash = implode("",$matches[0])."";
$hash = str_replace('#', ', ', $array_hash);
echo "hash (".$hash.")<br />";
echo $text;
Result:
hash (, h , gg)
#h #gg #مصر
I want a result like that:
hash (, h , gg , مصر)
#h #gg #مصر
To take whatever in UTF-8 we use this [^ \"\n\r\t<]*
i know its too late just for others to know
i modify this function to make it allow Arabic characters
as fallowing
function get_hashtags($string, $str = 1) {
preg_match_all('/#(\w*[a-zA-Z-أ-إ-آ-ا-ب-ت-ث-ج-ح-خ-د-ذ-ر-ز-س-ش-ص-ض-ط-ظ-ع-غ-ف-ق-ك-ل-م-ن-ه-و-لا-لا-لآ-لأ-لإ-ى-ي-ئ-ة-ء-ؤ_]+)/',$string,$matches);
$i = 0;
if ($str) {
foreach ($matches[1] as $match) {
$count = count($matches[1]);
$keywords .= "$match";
$i++;
if ($count > $i) $keywords .= ", ";
}
} else {
foreach ($matches[1] as $match) {
$keyword[] = $match;
}
$keywords = $keyword;
}
return $keywords;
}
usage :
$string = "<p>#عاشت #فلسطين حرة عربية يوجد 2 هاشتاج لازم اشوفهم في الداتا بيز</p>";
$myArray = get_hashtags($string, $str = 0);
$max = sizeof($myArray);
for($i = 0; $i < $max;$i++)
{
echo "#".$myArray[$i]."<br />";
}
echo "$string"
result
#عاشت
#فلسطين
#عاشت #فلسطين حرة عربية يوجد 2 هاشتاج لازم اشوفهم في الداتا بيز
I have this string:
525,294,475,215,365,745
and i need to remove 475..and comma.
and if i need to remove first number i need to remove also the next comma, also for last.
I can i do?
a regular expression?
thx
$newStr = str_replace(',475', '525,294,475,215,365,745');
Or the less error prone way:
$new = array();
$pieces = explode(',', '525,294,475,215,365,745');
foreach ($pieces as $piece) {
if ($piece != 475) {
$new[] = $piece;
}
}
$newStr = implode(',', $new);
Here's a regular expression:
$s = "525,294,475,215,365,745";
$s = preg_replace(',?475', '', $s);
$data = "525,294,475,215,365,745";
$parts = explode(',', $data);
for ($i = 0; $i < count($parts); $i++) {
if ($parts[$i] == 475) {
unset($parts[$i]);
}
}
$newdata = join(',', $parts);
<?php
$bigString = "525,294,475,215,365,745";
$pos = strpos($bigString, ",");
while($pos != false) {
$newString .= substr($bigString, 0, $pos);
$bigString = substr($bigString, $pos + 1);
$pos = strpos($bigString, ",");
}
echo $newString;
?>
function filterValue($index, &$a)
{
$key = array_search($index, $a);
if ($key != false) {
unset($a[$key]);
}
}
// Original data
$data = "525,294,475,215,365,745";
$data = explode(',', $data);
filterValue('475', $data);
$output = implode(',', $data);