Edit all odd words in string to upper case - php

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

Related

Replace the Nth occurrence of char in a string with a new substring

I want to do a str_replace() but only at the Nth occurrence.
Inputs:
$originalString = "Hello world, what do you think of today's weather";
$findString = ' ';
$nthOccurrence = 8;
$newWord = ' beautiful ';
Desired Output:
Hello world, what do you think of today's beautiful weather
Here is a tight little regex with \K that allows you to replace the nth occurrence of a string without repeating the needle in the pattern. If your search string is dynamic and might contain characters with special meaning, then preg_quote() is essential to the integrity of the pattern.
If you wanted to statically write the search string and nth occurrence into your pattern, it could be:
(?:.*?\K ){8}
or more efficiently for this particular case: (?:[^ ]*\K ){8}
\K tells the regex pattern to "forget" any previously matched characters in the fullstring match. In other words, "restart the fullstring match" or "Keep from here". In this case, the pattern only keeps the 8th space character.
Code: (Demo)
function replaceNth(string $input, string $find, string $replacement, int $nth = 1): string {
$pattern = '/(?:.*?\K' . preg_quote($find, '/') . '){' . $nth . '}/';
return preg_replace($pattern, $replacement, $input, 1);
}
echo replaceNth($originalString, $findString, $newWord, $nthOccurrence);
// Hello world, what do you think of today's beautiful weather
Another perspective on how to grapple the asked question is: "How to insert a new string after the nth instance of a search string?" Here is a non-regex approach that limits the explosions, prepends the new string to the last element then re-joins the elements. (Demo)
$originalString = "Hello world, what do you think of today's weather";
$findString = ' ';
$nthOccurrence = 8;
$newWord = 'beautiful '; // notice that leading space was removed
function insertAfterNth($input, $find, $newString, $nth = 1) {
$parts = explode($find, $input, $nth + 1);
$parts[$nth] = $newString . $parts[$nth];
return implode($find, $parts);
}
echo insertAfterNth($originalString, $findString, $newWord, $nthOccurrence);
// Hello world, what do you think of today's beautiful weather
I found an answer here - https://gist.github.com/VijayaSankarN/0d180a09130424f3af97b17d276b72bd
$subject = "Hello world, what do you think of today's weather";
$search = ' ';
$occurrence = 8;
$replace = ' nasty ';
/**
* String replace nth occurrence
*
* #param type $search Search string
* #param type $replace Replace string
* #param type $subject Source string
* #param type $occurrence Nth occurrence
* #return type Replaced string
*/
function str_replace_n($search, $replace, $subject, $occurrence)
{
$search = preg_quote($search);
echo preg_replace("/^((?:(?:.*?$search){".--$occurrence."}.*?))$search/", "$1$replace", $subject);
}
str_replace_n($search, $replace, $subject, $occurrence);
$originalString = "Hello world, what do you think of today's weather";
$findString = ' ';
$nthOccurrence = 8;
$newWord = ' beautiful ';
$array = str_split($originalString);
$count = 0;
$num = 0;
foreach ($array as $char) {
if($findString == $char){
$count++;
}
$num++;
if($count == $nthOccurrence){
array_splice( $array, $num, 0, $newWord );
break;
}
}
$newString = '';
foreach ($array as $char) {
$newString .= $char;
}
echo $newString;
I would consider something like:
function replaceNth($string, $substring, $replacement, $nth = 1){
$a = explode($substring, $string); $n = $nth-1;
for($i=0,$l=count($a)-1; $i<$l; $i++){
$a[$i] .= $i === $n ? $replacement : $substring;
}
return join('', $a);
}
$originalString = 'Hello world, what do you think of today\'s weather';
$test = replaceNth($originalString, ' ', ' beautiful ' , 8);
$test2 = replaceNth($originalString, 'today\'s', 'good');
First explode a string by parts, then concatenate the parts together and with search string, but at specific number concatenate with replace string (numbers here start from 0 for convenience):
function str_replace_nth($search, $replace, $subject, $number = 0) {
$parts = explode($search, $subject);
$lastPartKey = array_key_last($parts);
$result = '';
foreach($parts as $key => $part) {
$result .= $part;
if($key != $lastPartKey) {
if($key == $number) {
$result .= $replace;
} else {
$result .= $search;
}
}
}
return $result;
}
Usage:
$originalString = "Hello world, what do you think of today's weather";
$findString = ' ';
$nthOccurrence = 7;
$newWord = ' beautiful ';
$result = str_replace_nth($findString, $newWord, $originalString, $nthOccurrence);

How to print longest and shortest word from text file story.txt and find the frequency of each of them in php?

$string = file_get_contents('./story.txt', true);
$words = explode('\n', $string);
$w = array();
foreach ($words as $word) {
$temp = explode(' ', $word);
$w = array_merge($w, $temp);
}
$longestWordLength = 0;
$longestWord = '';
foreach ($w as $word) {
if (strlen($word) > $longestWordLength) {
$longestWordLength = strlen($word);
$longestWord = $word;
}
}
echo $longestWord;
echo strlen($longestWord);
I have written this code but it scans the ending word from one para and first word from next paragraph as same. In the following para:
arts along the stream looks almost like a flash of sunlight.
Desert animals are generally the color of the desert.
In this,
sunlight. Desert
is treated as one word.
You can try this way to get the longest string from the file text, I've removed extra spaces and dot characters from the array using array_map()
function longest_string_in_array($array) {
$array = array_map(function($item) { return trim($item, '. ');},$array);
$mapping = array_combine($array, array_map('strlen', $array));
return $mapping;
}
$string = file_get_contents('./story.txt', true);
$array = preg_split('/[\s]+/', $string );
print_r(longest_string_in_array($array));
So, I guess the answer to this handsome boy's problem is that those words are not splitting apart that are separated by anything other than single whitespace. In this case the solution is to use,
$string = file_get_contents('./story.txt', true);
$words = preg_split('/\s+/', $string);
and you're good to go.

Incremental strings in PHP

I want string format with incremental numbers. I've strings starting with alphabets and containing numbers with few leading 0's.
$string = M001; //input
$alf= trim(str_replace(range(0,9),'',$string)); //removes number from string
$number = preg_replace('/[A-Za-z]+/', '', $string);// removes alphabets from the string
$number+=1;
$custom_inv_id = $alf.$number;
Expected result:
input M002 output M003
input A00003 output A00004
Using above code if input is M002, I'm getting output as M3. How I can get M003? Number of 0's is not fixed.
Use PHP preg_match or str_replace and try this code :-
$str='M001';
preg_match('!\d+!', $str, $matches);
$num=(int)$matches[0];
$num++;
echo str_replace((int)$matches[0],'',$str);
echo $num;
Demo
<?php
$tests = ['M0', 'M1', 'M001', 'M9', 'M09', 'M010',
'M2M0', 'M2M1', 'M2M001', 'M2M9', 'M2M09', 'M2M010',
'M2M', 'MM', '9M'];
foreach ($tests as $string) {
if (preg_match('/([\w\W]+)([0-9]+)$/', $string, $matches)) {
$output_string = $matches[1] . ($matches[2] + 1);
echo '<p>' . $string . ' => ' . $output_string . '</p>';
} else {
echo '<p>' . $string . ' (nothing to increment)</p>';
}
}
$a = 'm002';
$pattern = '#(?P<word>[A-Za-z0]+)(?P<digtt>[1-9]+)#';
preg_match($pattern, $a, $matches);
$final = $matches['word'].(string)($matches['digtt']+1);
echo $final;
You can use the sprintf and preg_match functions to get your expected result.
First: Split your string with preg_match to seperated values to work with
Second: Format a new string with sprintf
http://php.net/manual/en/function.sprintf.php
http://php.net/manual/en/function.preg-match.php
function increase($string, $amount = 1) {
$valid = preg_match("#^(.)(0+)?(\d+)$#s", $string, $matches);
if($valid) {
list($match, $char, $zero, $integer) = $matches;
$integer += $amount;
return sprintf("%s%'.0" . (strlen($zero)+1) . "d", $char, $integer);
}
return null;
}
echo increase("M00001"); // M00002
echo increase("A001", 5); // A006
i hope this can help you . i have made some thing dynamic make M% also dynamic
<?php
$vl = "A00004";
$number = substr($vl ,1);
$num= substr_count($vl,0);
$num++;
$number++;
$string = "M%'. 0".$num."d";
echo sprintf($string, $number);
?>
i got this result
M00005
As leading 0 is copied, I would do it like this. It works if the leading chars is also lowercase. It's also a non-regex and non-array way.
$str = "M0099";
$num = ltrim($str, "a..zA..Z0");
$new = str_replace($num, $num + 1, $str);
Output:
echo $new; // string(6) "M00100"

Camelize a php string

How to convert this type of php string to camel case?
$string = primary-getallgroups-sys
I've tried but just found different solutions to camelize a string with spaces. Like ucword($string), but it just capitalize the first word. When i add a delimeter of hyphen (-), it gives error.
$string = 'primary-getallgroups-sys';
// split string by '-'
$words = explode('-', $string);
// make a strings first character uppercase
$words = array_map('ucfirst', $words);
// join array elements with '-'
$string = implode('-', $words);
echo $string; // is now Primary-Getallgroups-Sys
You can make a function to convert these types of string to camel cases.
Try this:
<?php
// CONVERT STRING TO CAMEL CASE SEPARATED BY A DELIMITER
function convertToCamel($str, $delim){
$exploded_str = explode($delim, $str);
$exploded_str_camel = array_map('ucwords', $exploded_str);
return implode($delim, $exploded_str_camel);
}
$string = 'primary-getallgroups-sys';
echo convertToCamel($string, '-'); // Answer
?>
In fact camel case is more like this: iAmCamelCased.
And this is mixed case: IAmMixedCased.
#sundas-mushtaq Also note that hyphens will break your code if used in symbol names (like in functions or variables).
To camelize, use this:
function camelize($word, $delimiter){
$elements = explode($delimiter, $word);
for ($i = 0; $i < count($elements); $i++) {
if (0 == $i) {
$elements[$i] = strtolower($elements[$i]);
} else {
$elements[$i] = strtolower($elements[$i]);
$elements[$i] = ucwords($elements[$i]);
}
}
return implode('', $elements);
}
And to mixify, use this :
function mixify($word, $delimiter){
$word = strtolower($word);
$word = ucwords($word, $delimiter);
return str_replace($delimiter, '', $word);
}
From Symfony
function camelize(string $string): string
{
return lcfirst(str_replace(' ', '', ucwords(preg_replace('/[^a-zA-Z0-9\x7f-\xff]++/', ' ', $string))));
}
// if you want to camelize first word also, remove lcfirst call
function camelize($string) {
$tokens = array_map("ucFirst", explode("_", $string)) ;
return lcfirst(implode("",$tokens));
}

PHP sentence case function

I have got a function from Google to clean my paragraph in sentence case.
I want to modify this function such that it converts more than 2 new line character to newline. Else it converts all new line characters in space. So I would have it in paragraph format. Here it's converting all new line character to space.
It's converting in proper sentence case. But, In case If I found single word having first word as capital then I need function to ignore that. As Sometimes, if there would be any noun It needs to be capital. We can't change it small case. Else if noun and it is having more than 2 capital characters other than first character than convert it to lower case.
Like -> Noun => Noun but NoUn => noun. Means I want if other than first character is capital than it convert it two lower case Else it keep it in same format.
function sentence_case($string) {
$sentences = preg_split('/([.?!]+)/', $string, -1, PREG_SPLIT_NO_EMPTY|PREG_SPLIT_DELIM_CAPTURE);
$new_string = '';
foreach ($sentences as $key => $sentence) {
$new_string .= ($key & 1) == 0?
ucfirst(strtolower(trim($sentence))) :
$sentence.' ';
}
$new_string = preg_replace("/\bi\b/", "I", $new_string);
//$new_string = preg_replace("/\bi\'\b/", "I'", $new_string);
$new_string = clean_spaces($new_string);
$new_string = m_r_e_s($new_string);
return trim($new_string);
}
function sentence_case($str) {
$cap = true;
$ret='';
for($x = 0; $x < strlen($str); $x++){
$letter = substr($str, $x, 1);
if($letter == "." || $letter == "!" || $letter == "?"){
$cap = true;
}elseif($letter != " " && $cap == true){
$letter = strtoupper($letter);
$cap = false;
}
$ret .= $letter;
}
return $ret;
}
This will preserve existing proper noun capitals, acronyms and abbreviations.
This should do it:
function sentence_case($string) {
// Protect the paragraphs and the caps
$parDelim = "/(\n+\r?)/";
$string = preg_replace($parDelim, "#PAR#", $string);
$string = preg_replace("/\b([A-Z])/", "#$1#", $string);
$sentences = preg_split('/([.?!]+)/', $string, -1, PREG_SPLIT_NO_EMPTY|PREG_SPLIT_DELIM_CAPTURE);
$new_string = '';
foreach ($sentences as $key => $sentence) {
$new_string .= ($key & 1) == 0?
ucfirst(strtolower(trim($sentence))) :
$sentence.' ';
}
$new_string = preg_replace("/\bi\b/", "I", $new_string);
//$new_string = preg_replace("/\bi\'\b/", "I'", $new_string);
$new_string = clean_spaces($new_string);
$new_string = m_r_e_s($new_string);
// Restore the paragraphs and the caps
$new_string = preg_replace("#PAR#", PHP_EOL, $new_string);
$new_string = preg_replace("/#([A-Z])#/", "$1", $new_string);
return trim($new_string);
}
It works by identifying the items you want to protect (paragraph & first cap) and marking it with a string that you can then replace back when you are done. The assumption is that you don't already have #PAR# and #A-Z# in the string. You can use whatever you want to use for the paragraph delimiter afterwards if you want to force a certain type of line ending or several lines in between.
Slightly modifying Sylverdrag's function, I got something that is working well for me. This version works for every messed-up sentence I've thrown at it so far :)
function sentence_case($string) {
$string = strtolower($string); // ADDED THIS LINE
// Protect the paragraphs and the caps
$parDelim = "/(\n+\r?)/";
$string = preg_replace($parDelim, "#PAR#", $string);
$string = preg_replace("/\b([A-Z])/", "#$1#", $string);
$sentences = preg_split('/([.?!]+)/', $string, -1, PREG_SPLIT_NO_EMPTY|PREG_SPLIT_DELIM_CAPTURE);
$new_string = '';
foreach ($sentences as $key => $sentence) {
$new_string .= ($key & 1) == 0?
ucfirst(strtolower(trim($sentence))) :
$sentence.' ';
}
$new_string = preg_replace("/\bi\b/", "I", $new_string);
// GOT RID OF THESE LINES
// $new_string = preg_replace("/\bi\'\b/", "I'", $new_string);
// $new_string = clean_spaces($new_string);
// $new_string = m_r_e_s($new_string);
// Restore the paragraphs and the caps
$new_string = preg_replace("#PAR#", PHP_EOL, $new_string);
$new_string = preg_replace("/#([A-Z])#/", "$1", $new_string);
$new_string = preg_replace("/#([A-Z])#/", "$1", $new_string);
preg_match('/#(.*?)#/', $new_string, $match); // MODIFIED THIS LINE TO USE (.*?)
return trim($new_string);
}
$string = "that IS it!! YOU and i are Totally DONE hanging out toGether... like FOREveR DUDE! i AM serious. a good FRIEND would NOT treAT me LIKE you dO. it Seems, howEVER, THAT you ARE not ONE of tHe GOOD ONEs.";
echo "<b>String 1:</b> " . $string . "<br><b>String 2:</b> " . sentence_case($string);
PHP Sandbox
:) :)

Categories