There is a string variable containing number data , say $x = "OP/99/DIR"; . The position of the number data may change at any circumstance by user desire by modifying it inside the application , and the slash bar may be changed by any other character ; but the number data is mandatory. How to replace the number data to a different number ? example OP/99/DIR is changed to OP/100/DIR.
$string="OP/99/DIR";
$replace_number=100;
$string = preg_replace('!\d+!', $replace_number, $string);
print $string;
Output:
OP/100/DIR
Assuming the number only occurs once:
$content = str_replace($originalText, $numberToReplace, $numberToReplaceWith);
To change the first occurance only:
$content = str_replace($originalText, $numberToReplace, $numberToReplaceWith, 1);
Using regex and preg_replace
$x="OP/99/DIR";
$new = 100;
$x=preg_replace('/\d+/e','$new',$x);
print $x;
The most flexible solution is to use preg_replace_callback() so you can do whatever you want with the matches. This matches a single number in the string and then replaces it for the number plus one.
root#xxx:~# more test.php
<?php
function callback($matches) {
//If there's another match, do something, if invalid
return $matches[0] + 1;
}
$d[] = "OP/9/DIR";
$d[] = "9\$OP\$DIR";
$d[] = "DIR%OP%9";
$d[] = "OP/9321/DIR";
$d[] = "9321\$OP\$DIR";
$d[] = "DIR%OP%9321";
//Change regexp to use the proper separator if needed
$d2 = preg_replace_callback("(\d+)","callback",$d);
print_r($d2);
?>
root#xxx:~# php test.php
Array
(
[0] => OP/10/DIR
[1] => 10$OP$DIR
[2] => DIR%OP%10
[3] => OP/9322/DIR
[4] => 9322$OP$DIR
[5] => DIR%OP%9322
)
Related
I am new to PHP Development and finally with the help of SO I am able to write a program for finding word in a sentence with maximum specific character count.
Below is what I have tried:
<?php
// Program to find the word in a sentence with maximum specific character count
// Example: "O Romeo, Romeo, wherefore art thou Romeo?”
// Solution: wherefore
// Explanation: Because "e" came three times
$content = file_get_contents($argv[1]); // Reading content of file
$max = 0;
$arr = explode(" ", $content); // entire array of strings with file contents
for($x =0; $x<count($arr); $x++) // looping through entire array
{
$array[$x] = str_split($arr[$x]); // converting each of the string into array
}
for($x = 0; $x < count($arr); $x++)
{
$count = array_count_values($array[$x]);
$curr_max = max($count);
if($curr_max > $max)
{
$max = $curr_max;
$word = $arr[$x];
}
}
echo $word;
?>
Question: Since I am new to PHP development I don't know the optimization techniques. Is there anyway I can optimize this code? Also, Can I use regex to optimize this code further? Kindly guide.
I love coding this type of mini-challenges in the minimum lines of code :D. So here is my solution:
function wordsWithMaxCharFrequency($sentence) {
$words = preg_split('/\s+/', $sentence);
$maxCharsFrequency = array_map (function($word) {
return max(count_chars(strtolower($word)));
}, $words);
return array_map(function($index) use($words) {
return $words[$index];
}, array_keys($maxCharsFrequency, max($maxCharsFrequency)));
}
print_r(wordsWithMaxCharFrequency("eeee yyyy"));
//Output: Array ( [0] => eeee [1] => yyyy )
print_r(wordsWithMaxCharFrequency("xx llll x"));
//Output: Array ( [0] => llll )
Update1:
If you want to get only A-Za-z words use the following code:
$matches = [];
//a word is either followed by a space or end of input
preg_match_all('/([a-z]+)(?=\s|$)/i', $sentence, $matches);
$words = $matches[1];
Just a contribution that could inspire you :D!
Good Luck.
How to check substrings in PHP by prefix or postfix.
For example, I have the search string named as $to_search as follows:
$to_search = "abcdef"
And three cases to check the if that is the substring in $to_search as follows:
$cases = ["abc def", "def", "deff", ... Other values ...];
Now I have to detect the first three cases using substr() function.
How can I detect the "abc def", "def", "deff" as substring of "abcdef" in PHP.
You might find the Levenshtein distance between the two words useful - it'll have a value of 1 for abc def. However your problem is not well defined - matching strings that are "similar" doesn't mean anything concrete.
Edit - If you set the deletion cost to 0 then this very closely models the problem you are proposing. Just check that the levenshtein distance is less than 1 for everything in the array.
This will find if any of the strings inside $cases are a substring of $to_search.
foreach($cases as $someString){
if(strpos($to_search, $someString) !== false){
// $someString is found inside $to_search
}
}
Only "def" is though as none of the other strings have much to do with each other.
Also on a side not; it is prefix and suffix not postfix.
To find any of the cases that either begin with or end with either the beginning or ending of the search string, I don't know of another way to do it than to just step through all of the possible beginning and ending combinations and check them. There's probably a better way to do this, but this should do it.
$to_search = "abcdef";
$cases = ["abc def", "def", "deff", "otherabc", "noabcmatch", "nodefmatch"];
$matches = array();
$len = strlen($to_search);
for ($i=1; $i <= $len; $i++) {
// get the beginning and end of the search string of length $i
$pre_post = array();
$pre_post[] = substr($to_search, 0, $i);
$pre_post[] = substr($to_search, -$i);
foreach ($cases as $case) {
// get the beginning and end of each case of length $i
$pre = substr($case, 0, $i);
$post = substr($case, -$i);
// check if any of them match
if (in_array($pre, $pre_post) || in_array($post, $pre_post)) {
// using the case as the array key for $matches will keep it distinct
$matches[$case] = true;
}
}
}
// use array_keys() to get the keys back to values
var_dump(array_keys($matches));
You can use array_filter function like this:
$cases = ["cake", "cakes", "flowers", "chocolate", "chocolates"];
$to_search = "chocolatecake";
$search = strtolower($to_search);
$arr = array_filter($cases, function($val) use ($search) { return
strpos( $search,
str_replace(' ', '', preg_replace('/s$/', '', strtolower($val))) ) !== FALSE; });
print_r($arr);
Output:
Array
(
[0] => cake
[1] => cakes
[3] => chocolate
[4] => chocolates
)
As you can it prints all the values you expected apart from deff which is not part of search string abcdef as I commented above.
I have this string: $delims = ',^.;:\t' (which is used in a preg_replace() call).
I need two arrays .. one with those delimiters as the index ($delimCount), and another with those delimiters as the values ($delimiters).
The former will get values assigned from within a loop on the latter .. as such:
foreach ($delimiters as $delim) {
if( strpos($char, $delim) !== false) { // if the char is the delim ...
$delimCount[$delim]++; // ... increment
}
}
The way I have it now is messy, and I'd like to simply break that string into the two arrays ... but I'm getting tripped up on the \t delimiter (because it's the only one with two characters).
How can/should I handle that?
How I would handle your \t delimiter
$delims = ',^.;:\t';
$i = 0;
while($i < strlen($delims)) {
if($delims[$i] == chr(92)) {
$delimiters[] = $delims[$i] . $delims[$i+1];
$i = $i + 2;
}
else {
$delimiters[] = $delims[$i];
$i++;
}
}
Output of $delimiters
Array
(
[0] => ,
[1] => ^
[2] => .
[3] => ;
[4] => :
[5] => \t
)
As far as an array with the delimiters as an index
foreach($delimiters as $key=>$val) {
$delimCount[$val] = $val;
}
Output of $delimCount
Array
(
[,] => ,
[^] => ^
[.] => .
[;] => ;
[:] => :
[\t] => \t
)
Hope this helps.
I need two arrays .. one with those delimiters as the index ($delimCount), and another with those delimiters as the values ($delimiters).
Well, where does $delimiters come from? Did you write it yourself? If so, I'd argue you'd be better off making $delimiters an array in any case, and using implode when you use it in preg_replace.
If you have a problem with tabulator, then you can use ordinal number of character as the key inplace of character itself: $delim = "\t"; $delimCount[ ord($delim) ]++;
Handy complementary functions: ord() and chr().
I have string:
ABCDEFGHIJK
And I have two arrays of positions in that string that I want to insert different things to.
Array
(
[0] => 0
[1] => 5
)
Array
(
[0] => 7
[1] => 9
)
Which if I decided to add the # character and the = character, it'd produce:
#ABCDE=FG#HI=JK
Is there any way I can do this without a complicated set of substr?
Also, # and = need to be variables that can be of any length, not just one character.
You can use string as array
$str = "ABCDEFGH";
$characters = preg_split('//', $str, -1);
And afterwards you array_splice to insert '#' or '=' to position given by array
Return the array back to string is done by:
$str = implode("",$str);
This works for any number of characters (I am using "#a" and "=b" as the character sequences):
function array_insert($array,$pos,$val)
{
$array2 = array_splice($array,$pos);
$array[] = $val;
$array = array_merge($array,$array2);
return $array;
}
$s = "ABCDEFGHIJK";
$arr = str_split($s);
$arr_add1 = array(0=>0, 1=>5);
$arr_add2 = array(0=>7, 1=>9);
$char1 = '#a';
$char2 = '=b';
$arr = array_insert($arr, $arr_add1[0], $char1);
$arr = array_insert($arr, $arr_add1[1] + strlen($char1), $char2);
$arr = array_insert($arr, $arr_add2[0]+ strlen($char1)+ strlen($char2), $char1);
$arr = array_insert($arr, $arr_add2[1]+ strlen($char1)+ strlen($char2) + strlen($char1), $char2);
$s = implode("", $arr);
print_r($s);
There is an easy function for that: substr_replace. But for this to work, you would have to structure you array differently (which would be more structured anyway), e.g.:
$replacement = array(
0 => '#',
5 => '=',
7 => '#',
9 => '='
);
Then sort the array by keys descending, using krsort:
krsort($replacement);
And then you just need to loop over the array:
$str = "ABCDEFGHIJK";
foreach($replacement as $position => $rep) {
$str = substr_replace($str, $rep, $position, 0);
}
echo $str; // prints #ABCDE=FG#HI=JK
This works by inserting the replacements starting from the end of string. And it would work with any replacement string without having to determine the length of that string.
Working DEMO
In php I need to Load a file and get all of the words and echo the word and the number of times each word shows up in the text,
(I also need them to show up in descending order most used words on top) ★✩
Here's an example:
$text = "A very nice únÌcÕdë text. Something nice to think about if you're into Unicode.";
// $words = str_word_count($text, 1); // use this function if you only want ASCII
$words = utf8_str_word_count($text, 1); // use this function if you care about i18n
$frequency = array_count_values($words);
arsort($frequency);
echo '<pre>';
print_r($frequency);
echo '</pre>';
The output:
Array
(
[nice] => 2
[if] => 1
[about] => 1
[you're] => 1
[into] => 1
[Unicode] => 1
[think] => 1
[to] => 1
[very] => 1
[únÌcÕdë] => 1
[text] => 1
[Something] => 1
[A] => 1
)
And the utf8_str_word_count() function, if you need it:
function utf8_str_word_count($string, $format = 0, $charlist = null)
{
$result = array();
if (preg_match_all('~[\p{L}\p{Mn}\p{Pd}\'\x{2019}' . preg_quote($charlist, '~') . ']+~u', $string, $result) > 0)
{
if (array_key_exists(0, $result) === true)
{
$result = $result[0];
}
}
if ($format == 0)
{
$result = count($result);
}
return $result;
}
$words = str_word_count($text, 1);
$word_frequencies = array_count_values($words);
arsort($word_frequencies);
print_r($word_frequencies);
This function uses a regex to find words (you might want to change it, depending on what you define a word as)
function count_words($text)
{
$output = $words = array();
preg_match_all("/[A-Za-z'-]+/", $text, $words); // Find words in the text
foreach ($words[0] as $word)
{
if (!array_key_exists($word, $output))
$output[$word] = 0;
$output[$word]++; // Every time we find this word, we add 1 to the count
}
return $output;
}
This iterates over each word, constructing an associative array (with the word as the key) where the value refers to the occurences of each word. (e.g. $output['hello'] = 3 => hello occured 3 times in the text).
Perhaps you might want to change the function to deal with case insensitivity (i.e. 'hello' and 'Hello' are not the same word, according to this function).
echo count(explode('your_word', $your_text));