How to make str_ireplace same case - php

How to make str_ireplace same lowercase and uppercase.
example
$letters = array('jonny', 'gennie');
$fruit = array('ponny', 'petty');
$text = 'JONNY love Gennie';
$output = str_ireplace($letters, $fruit, $text);
echo $output;
so the actually output is :
ponny love petty
but i want like this
PONNY love Petty
how to do it? actually i just need it if first letter is uppercase or all letters are uppercase.

you're using explicit hard coded values in your example, so the easiest is to use str_replace instead of str_ireplace, and just do a pass for both lowercase and uppercase string replacements. You can simply build the uppercase and sentence case arrays off the lower case array, and then you don't even need to do any work:
$find_lc = array('moo', 'cow', 'something');
$find_uc = array_map('str_to_upper', $array);
$find_sc = array_map('ucfirst', $array);
$searches = array($find_lc, $find_uc, $find_sc);
$replace_lc = array(...);
$replace_uc = array(...);
$replace_sc = array(...);
$replacements = array($replace_lc, $replace_uc, $replace_sc);
$converted = $input;
for($i=0; $i<count($searches); $i++) {
$converted = str_replace($searches[$i], $replacements[$i], $converted);
}
And now it'll simply be correctly case-replaced. A little verbose perhaps, and you need hardcoded lists, but your question seemed pretty specific instead of asking about "any possible word" (in which case you'll need to use something like preg_replace_callback)

Related

PhP regex for a string, what would be the best way to do it?

I have an array with rule field that has a string like this:
FREQ=MONTHLY;BYDAY=3FR
FREQ=MONTHLY;BYDAY=3SA
FREQ=WEEKLY;UNTIL=20170728T080000Z;BYDAY=MO,TU,WE,TH,FR
FREQ=MONTHLY;UNTIL=20170527T100000Z;BYDAY=4SA
FREQ=WEEKLY;BYDAY=SA
FREQ=WEEKLY;INTERVAL=2;BYDAY=TH
FREQ=WEEKLY;BYDAY=TH
FREQ=WEEKLY;UNTIL=20170610T085959Z;BYDAY=SA
FREQ=MONTHLY;BYDAY=2TH
Each line is a different array, I am giving a few clues to get an idea of what I need.
What I need is to write a regex that would take off all unnecessary values.
So, I don't need FREQ= ; BYDAY= etc. I basically need the values after = but each one I want to store in a different variable.
Taking third one as an example it would be:
$frequency = WEEKLY
$until = 20170728T080000Z
$day = MO, TU, WE, TH, FR
It doesn't have to be necessarily one regex, there can be one regex for each value. So I have one for FREQ:
preg_match("/[^FREQ=][A-Z]+/", $input_line, $output_array);
But I can't do it for the rest unfortunately, how can I solve this?
The only way to go would be PHP array destructuring:
$str = "FREQ=WEEKLY;UNTIL=20170728T080000Z;BYDAY=MO,TU,WE,TH,FR";
preg_match_all('~(\w+)=([^;]+)~', $str, $matches);
[$freq, $until, $byday] = $matches[2]; // As of PHP 7.1 (otherwise use list() function)
echo $freq, " ", $until, " ", $byday;
// WEEKLY 20170728T080000Z MO,TU,WE,TH,FR
Live demo
Be more general
Using extract function:
preg_match_all('~(\w+)=([^;]+)~', $str, $m);
$m[1] = array_map('strtolower', $m[1]);
$vars = array_combine($m[1], $m[2]);
extract($vars);
echo $freq, " ", $until, " ", $byday;
Live demo
Notice: For this problem, I recommend the generell approach #revo posted, it's concise and safe and easy on the eyes -- but keep in mind, that regular expressions come with a performance penalty compared to fixed string functions, so if you can use strpos/substr/explode/..., try to use them, don't 'knee-jerk' to a preg_-based solution.
Since the seperators are fixed and don't seem to occur in the values your are interested in, and you furthermore rely on knowledge of the keys (FREQ:, etc) you don't need regular-expressions (as much as I like to use them anywhere I can, and you can use them here); why not simply explode and split in this case?
$lines = explode("\n", $text);
foreach($lines as $line) {
$parts = explode(';', $line);
$frequency = $until = $day = $interval = null;
foreach($parts as $part) {
list($key, $value) = explode('=', $part);
switch($key) {
case 'FREQ':
$frequency = $value;
break;
case 'INTERVAL':
$interval = $value;
break;
// and so on
}
}
doSomethingWithTheValues();
}
This may be more readable and efficient if your use-case is as simple as stated.
You need to use the Pattern
;?[A-Z]+=
together with preg_split();
preg_split('/;?[A-Z]+=/', $str);
Explanation
; match Semikolon
? no or one of the last Character
[A-Z]+ match one or more uppercase Letters
= match one =
If you want to have each Line into a seperate Array, you should do it this Way:
# split each Line into an Array-Element
$lines = preg_split('/[\n\r]+/', $str);
# initiate Array for Results
$results = array();
# start Looping trough Lines
foreach($lines as $line){
# split each Line by the Regex mentioned above and
# put the resulting Array into the Results-Array
$results[] = preg_split('/;?[A-Z]+=/', $line);
}

PHP get everything in a string before underscore

I have this code here:
$imagePreFix = substr($fileinfo['basename'], strpos($fileinfo['basename'], "_") +1);
this gets me everything after the underscore, but I am looking to get everything before the underscore, how would I adjust this code to get everything before the underscore?
$fileinfo['basename'] is equal to 'feature_00'
Thanks
You should simple use:
$imagePreFix = substr($fileinfo['basename'], 0, strpos($fileinfo['basename'], "_"));
I don't see any reason to use explode and create extra array just to get first element.
You can also use (in PHP 5.3+):
$imagePreFix = strstr($fileinfo['basename'], '_', true);
If you are completely sure that there always be at least one underscore, and you are interested in first one:
$str = $fileinfo['basename'];
$tmp = explode('_', $str);
$res = $tmp[0];
Other way to do this:
$str = "this_is_many_underscores_example";
$matches = array();
preg_match('/^[a-zA-Z0-9]+/', $str, $matches);
print_r($matches[0]); //will produce "this"
(probably regexp pattern will need adjustments, but for purpose of this example it works just fine).
I think the easiest way to do this is to use explode.
$arr = explode('_', $fileinfo['basename']);
echo $arr[0];
This will split the string into an array of substrings. The length of the array depends on how many instances of _ there was. For example
"one_two_three"
Would be broken into an array
["one", "two", "three"]
Here's some documentation
If you want an old-school answer in the type of what you proposed you can still do the following:
$imagePreFix = substr($fileinfo['basename'], 0, strpos($fileinfo['basename'], "_"));

PHP String into array keyed by word start

Say I have the following string
$str = "once in a great while a good-idea turns great";
What would be the best solution to creating an array with the array key being the string count of where the word(s) starts?
$str_array['0'] = "once";
$str_array['5'] = "in";
$str_array['8'] = "a";
$str_array['10'] = "great";
$str_array['16'] = "while";
$str_array['22'] = "a";
$str_array['24'] = "good-idea";
$str_array['34'] = "turns";
$str_array['40'] = "great";
As simple as the following:
str_word_count($str, 2);
what str_word_count() does is
str_word_count() — Return information about words used in a string
str_word_count() with 2 as the second argument to get the the offset; and you'd probably need to use the 3rd argument to include hyphen as well as letters in words
$str = "once in a great while a good-idea turns great";
print_r(str_word_count($str, 2));
demo:
http://sandbox.onlinephpfunctions.com/code/9e1afc68725c1472fc595b54c5f8a8abf4620dfc
Try this:
$array = preg_split("/ /",$str,-1,PREG_SPLIT_OFFSET_CAPTURE);
$str_array = Array();
foreach($array as $word) $str_array[$word[1]] = $word[0];
EDIT: Just saw Mark Baker's answer. Probably a better option than mine!
You can use preg_split (with the PREG_SPLIT_OFFSET_CAPTURE option) to split the string on the space, then use the offset it gives you to make a new array.
$str = "once in a great while a good-idea turns great";
$split_array = preg_split('/ /', $str, -1, PREG_SPLIT_OFFSET_CAPTURE);
$str_array = array();
foreach($split_array as $split){
$str_array[$split[1]] = $split[0];
}

mb_eregi_replace multiple matches get them

$string = 'test check one two test3';
$result = mb_eregi_replace ( 'test|test2|test3' , '<$1>' ,$string ,'i');
echo $result;
This should deliver: <test> check one two <test3>
Is it possible to get, that test and test3 was found, without using another match function ?
You can use preg_replace_callback instead:
$string = 'test check one two test3';
$matches = array();
$result = preg_replace_callback('/test|test2|test3/i' , function($match) use ($matches) {
$matches[] = $match;
return '<'.$match[0].'>';
}, $string);
echo $result;
Here preg_replace_callback will call the passed callback function for each match of the pattern (note that its syntax differs from POSIX). In this case the callback function is an anonymous function that adds the match to the $matches array and returns the substitution string that the matches are to be replaced by.
Another approach would be to use preg_split to split the string at the matched delimiters while also capturing the delimiters:
$parts = preg_split('/test|test2|test3/i', $string, null, PREG_SPLIT_DELIM_CAPTURE);
The result is an array of alternating non-matching and matching parts.
As far as I know, eregi is deprecated.
You could do something like this:
<?php
$str = 'test check one two test3';
$to_match = array("test", "test2", "test3");
$rep = array();
foreach($to_match as $val){
$rep[$val] = "<$val>";
}
echo strtr($str, $rep);
?>
This too allows you to easily add more strings to replace.
Hi following function used to found the any word from string
<?php
function searchword($string, $words)
{
$matchFound = count($words);// use tha no of word you want to search
$tempMatch = 0;
foreach ( $words as $word )
{
preg_match('/'.$word.'/',$string,$matches);
//print_r($matches);
if(!empty($matches))
{
$tempMatch++;
}
}
if($tempMatch==$matchFound)
{
return "found";
}
else
{
return "notFound";
}
}
$string = "test check one two test3";
/*** an array of words to highlight ***/
$words = array('test', 'test3');
$string = searchword($string, $words);
echo $string;
?>
If your string is utf-8, you could use preg_replace instead
$string = 'test check one two test3';
$result = preg_replace('/(test3)|(test2)|(test)/ui' , '<$1>' ,$string);
echo $result;
Oviously with this kind of data to match the result will be suboptimal
<test> check one two <test>3
You'll need a longer approach than a direct search and replace with regular expressions (surely if your patterns are prefixes of other patterns)
To begin with, the code you want to enhance does not seem to comply with its initial purpose (not at least in my computer). You can try something like this:
$string = 'test check one two test3';
$result = mb_eregi_replace('(test|test2|test3)', '<\1>', $string);
echo $result;
I've removed the i flag (which of course makes little sense here). Still, you'd still need to make the expression greedy.
As for the original question, here's a little proof of concept:
function replace($match){
$GLOBALS['matches'][] = $match;
return "<$match>";
}
$string = 'test check one two test3';
$matches = array();
$result = mb_eregi_replace('(test|test2|test3)', 'replace(\'\1\')', $string, 'e');
var_dump($result, $matches);
Please note this code is horrible and potentially insecure. I'd honestly go with the preg_replace_callback() solution proposed by Gumbo.

Slice sentences in a text and storing them in variables

I have some text inside $content var, like this:
$content = $page_data->post_content;
I need to slice the content somehow and extract the sentences, inserting each one inside it's own var.
Something like this:
$sentence1 = 'first sentence of the text';
$sentence2 = 'second sentence of the text';
and so on...
How can I do this?
PS
I am thinking of something like this, but I need somekind of loop for each sentence:
$match = null;
preg_match('/(.*?[?\.!]{1,3})/', $content, $match);
$sentence1 = $match[1];
$sentence2 = $match[2];
Ty:)
Do you need them in variables? Can't you use a array?
$sentence = explode(". ", $page_data->post_content);
EDIT:
If you need variables:
$allSentence = explode(". ", $page_data->post_content);
foreach($allSentence as $key => $val)
{
${"sentence". $key} = $val;
}
Assuming each sentence ends with full stop, you can use explode:
$content = $page_data->post_content;
$sentences = explode('.', $content);
Now your sentences can be accessed like:
echo $sentences[0]; // 1st sentence
echo $sentences[1]; // 2nd sentence
echo $sentences[2]; // 3rd sentence
// and so on
Note that you can count total sentences using count or sizeof:
echo count($sentences);
It is not a good idea to create a new variable for each sentence, imagine you might have long piece of text which would require to create that number of variables there by increasing memory usage. You can simply use array index $sentences[0], $sentences[1] and so on.
Assuming a sentence is delimited by terminating punctuation, optionally followed by a space, you can do the following to get the sentences in an array.
$sentences = preg_split('/[!?\.]\s?/', $content);
You may want to trim any additional spaces as well with
$sentences = array_map('trim', $sentences);
This way, $sentences[0] is the first, $sentences[1] is the second and so on. If you need to loop through them you can use foreach:
foreach($sentences as $sentence) {
// Do something with $sentence...
}
Don't use individually named variables like $sentence1, $sentence2 etc. Use an array.
$sentences = explode('.', $page_data->post_content);
This gives you an array of the "sentences" in the variable $page_data->post_content, where "sentences" really means sequences of characters between full stops. This logic will get tripped up wherever a full stop is used to mean something other than the end of a sentence (e.g. "Mr. Watson").
Edit: Of course, you can use more sophisticated logic to detect sentence boundaries, as you have suggested. You should still use an array, not create an unknown number of variables with numbers on the ends of their names.

Categories