Could you tell how to replace by regular expression - php

Could you tell how to replace string by preg-replace (need regular expression):
/user/{parent_id}/{action}/step/1
At the equivalent values of an array:
array('parent_id'=>32, 'action'=>'some');
To make:
/user/32/some/step/1
Addition
This is a typical problem, so I probably will not know what the names of variables come

You can use str_replace
For example:
str_replace(array("{parent_id}", "{action}"), array(32, 'some'), "/user/{parent_id}/{action}/step/1");

$arr = array('parent_id'=>32, 'action'=>'some');
$out = str_replace(array_keys($arr),array_values($arr),$in);
no need for regexps!

Say you have:
$arr = array('parent_id'=>32, 'action'=>'some');
$in = '/usr/{parent_id}/{action}/step/1';
This will replace the braces:
function bracelize($str) {
return '{' . $str . '}';
}
$search = array_map('bracelize', array_keys($arr));
$out = str_replace($search, $arr, $in);
Or if you are using PHP >= 5.3 you can use lambdas:
$search = array_map(function ($v) { return '{'.$v.'}';}, array_keys($arr));
$out = str_replace($search, $arr, $in);

$s = '/user/{parent_id}/{action}/step/1';
$replacement = array('parent_id'=>32, 'action'=>'some');
$res = preg_replace(array('/\\{parent_id\\}/', '/\\{action\\}/'), $replacement, $s);
Of course, you could just as well use str_replace (in fact, you ought to).

<?php
$string = '/usr/{parent_id}/{action}/step/1';
$pattern = array('#{parent_id}#', '#{action}#');
$values = array('32', 'some');
echo preg_replace($pattern, $values, $string);
?>
If your problem is not more complicated than this, i would recommend changing preg_replace to str_replace though.
EDIT: I see you don't know the variable names in advance. In which case you could do something like this.
<?php
function wrap_in_brackets(&$item)
{
$item = '{' . $item . '}';
return true;
}
$string = '/usr/{parent_id}/{action}/step/1';
$variables = array('parent_id' => 32, 'action' => 'some');
$keys = array_keys($variables);
array_walk($keys, 'wrap_in_brackets');
echo str_replace($keys, array_values($variables), $string);
?>

Expanding on mvds' answer:
$in = 'user/{parent_id}/{action}/step/1';
$arr = array('{parent_id}' => 32, '{action}' => 'some');
$out = str_replace(array_keys($arr), $arr, $in);
Or:
$in = 'user/{parent_id}/{action}/step/1';
$arr = array('parent_id' => 32, 'action' => 'some');
$arr[] = '';
$find = array_merge(array_keys($arr), array('{', '}'));
$out = str_replace($find, $arr, $in);

Related

How can I convert a CSV string to HTML tags?

Here is my string:
$str = "php,html,css";
And this is expected result:
$newstr = "<a href='?t=php'>php</a><a href='?t=html'>html</a><a href='?t=css'>css</a>"
What's the cleanest way to do that by PHP?
I can do that by exploding that string and make it like this:
$arr = explode(",", $str);
$html = '';
foreach( $arr as $tag ){
$html .= "<a href='?t=$tag'>$tag</a>";
}
$newstr = $html;
But I guess that's not what a professional programmer will do.
You could use str_getcsv(), array_map(), sprintf(), and implode():
$str = "php,html,css";
$newstr = implode('', array_map(function ($type) {
return sprintf(
'%s',
$type,
$type
);
}, str_getcsv($str)));
For reference, see:
http://php.net/manual/en/function.str-getcsv.php
http://php.net/manual/en/function.array-map.php
http://php.net/manual/en/function.sprintf.php
http://php.net/manual/en/function.implode.php
For an example, see:
https://3v4l.org/n3PSS
Alternatively, you could use str_getcsv(), array_reduce(), and sprintf():
$str = "php,html,css";
$newstr = array_reduce(str_getcsv($str), function ($carry, $type) {
return $carry . sprintf(
'%s',
$type,
$type
);
}, '');
For reference, see:
http://php.net/manual/en/function.str-getcsv.php
http://php.net/manual/en/function.array-reduce.php
http://php.net/manual/en/function.sprintf.php
For an example, see:
https://3v4l.org/r7WIR

php match a string from other string

I have a string as $test = 'aa,bb,cc,dd,ee' and other string as $match='cc'. I want the result as $result='aa,bb,dd,ee'.
I am not able to get te result as desired as not sure which PHP function can give the desired output.
Also if I have a string as $test = 'aa,bb,cc,dd,ee' and other string as $match='cc'. I want the result as $match=''. i.e if $match is found in $test then $match value can be skipped
Any help will be really appreciated.
You can try with:
$test = 'aa,bb,cc,dd,ee';
$match = 'cc';
$output = trim(str_replace(',,', ',', str_replace($match, '', $test), ','));
or:
$testArr = explode(',', $test);
if(($key = array_search($match, $testArr)) !== false) {
unset($testArr[$key]);
}
$output = implode(',', $testArr);
Try with preg_replace
$test = 'aa,bb,cc,dd,ee';
$match ='cc';
echo $new = preg_replace('/'.$match.',|,'.$match.'$/', '', $test);
Output
aa,bb,dd,ee
$test = 'aa,bb,cc,dd,ee';
$match='cc';
echo trim(str_replace(',,', ',' , str_replace($match,'',$test)),',');
DEMO
Try this:
$test = 'aa,bb,cc,dd,ee';
$match = 'cc';
$temp = explode(',', $test);
unset($temp[ array_search($match, $temp) ] );
$result = implode(',', $temp);
echo $result;

complex regex with preg_replace, replace a word not inside [ and ]

I'm having trouble finding a correct regex to achieve what I want.
I have a sentence like that :
Hi, my name is Stan, you are welcome, hello.
and I would like to transform it like that :
[hi|hello|welcome], my name is [stan|jack] you are [hi|hello|welcome] [hi|hello|welcome].
Right now my regex is half working, because somes words are not replaced, and those replaced are deleting some characters
Here is my test code
<?php
$test = 'Hi, my name is Stan, you are welcome, hello.';
$words = array(
array('hi', 'hello', 'welcome'),
array('stan', 'jack'),
);
$result = $test;
foreach ($words as $group) {
if (count($group) > 0) {
$replacement = '[' . implode('|', $group) . ']';
foreach ($group as $word) {
$result = preg_replace('#([^\[])' . $word . '([^\]])#i', $replacement, $result);
}
}
}
echo $test . '<br />' . $result;
Any help will be appreciated
The regex you are using is overcomplicated. You simply need to use a regex substitution using regular brackets ():
<?php
$test = 'Hi, my name is Stan, you are welcome, hello.';
$words = array(
array('hi', 'hello', 'welcome'),
array('stan', 'jack'),
);
$result = $test;
foreach ($words as $group) {
if (count($group) > 0) {
$imploded = implode('|', $group);
$replacement = "[$imploded]";
$search = "($imploded)";
$result = preg_replace("/$search/i", $replacement, $result);
}
}
echo $test . '<br />' . $result;
Your regular expression:
'#([^\[])' . $word . '([^\]])#i'
matches one character before and after $word as well. And as they do, they replace it. So your replacement string needs to reference these parts, too:
'$1' . $replacement . '$2'
Demo
preg_replace supports array as parameter. No need to iterate with a loop.
$s = array("/(hi|hello|welcome)/i", "/(stan|jack)/i");
$r = array("[hi|hello|welcome]", "[stan|jack]");
preg_replace($s, $r, $str);
or dynamically
$test = 'Hi, my name is Stan, you are welcome, hello.';
$s = array("hi|hello|welcome", "stan|jack");
$r = array_map(create_function('$a','return "[$a]";'), $s);
$s = array_map(create_function('$a','return "/($a)/i";'), $s);
echo preg_replace($s, $r, $str);
//[hi|hello|welcome], my name is [stan|jack], you are [hi|hello|welcome], [hi|hello|welcome].

str_replace doesn't work with foreach

My code:
$str = array(
'{$string1}' => 'anything2',
'{$string2}' => 'something1',
'{$string3}' => '...'
);
$final = "";
$text = $_POST['content'];
foreach( $str as $key => $val ) {
$final = str_replace($key, $val, $text);
}
My $text ofc. has {string1} , {string2} and {string3} itself, but it doesn't replace it with the values given in the array.
Why its not working?
This code does exactly what you need (without any extra loops):
$final = strtr($_POST['content'], $str);
use
$final = str_replace('{'.$key.'}', $val, $text);
Ref : http://php.net/manual/en/function.str-replace.php
Maybe the different enconding, try this:
$text = utf8_decode($_POST['content']);// or utf8_encode
before loop;
Good lucky!

Replace everything from beginning of line to equal sign

For a content with the format:
KEY=VALUE
like:
LISTEN=I am listening.
I need to do some replacing using regex. I want this regular expression to replace anything before the = with $key (making it have to be from beginning of line so a key like 'EN' wont replace a key like "TOKEN".
Here's what I'm using, but it doesn't seem to work:
$content = preg_replace('~^'.$key.'\s?=[^\n$]+~iu',$newKey,$content);
$content = "foo=one\n"
. "bar=two\n"
. "baz=three\n";
$keys = array(
'foo' => 'newFoo',
'bar' => 'newBar',
'baz' => 'newBaz',
);
foreach ( $keys as $oldKey => $newKey ) {
$oldKey = preg_quote($oldKey, '#');
$content = preg_replace("#^{$oldKey}( ?=)#m", "{$newKey}\\1", $content);
}
echo $content;
Output:
newFoo=one
newBar=two
newBaz=three
$str = 'LISTEN=I am listening.';
$new_key = 'ÉCOUTER';
echo preg_replace('/^[^=]*=/', $new_key . '=', $str);
If I understood your question well, you need to switch the multi-line mode on using m modifier.
$content = preg_replace('/^'.preg_quote($key, '/').'(?=\s?=)/ium', $newKey, $content);
By the way I do recommend to escape the $key using preg_quote to avoid unexpected results.
So if the source content is this:
KEY1=VALUE1
HELLO=WORLD
KEY3=VALUE3
The result will be this (if $key=HELLO and $newKey=BYE):
KEY1=VALUE1
BYE=WORLD
KEY3=VALUE3
This should do the trick.
\A is the start of a line, and the parentheses is for grouping things to keep/replace.
$new_content = preg_replace("/\A(.*)(=.*)/", "$key$2", $content);
$content = 'LISTEN=I am listening.';
$key = 'LISTEN';
$newKey = 'NEW';
$content = preg_replace('~^'.$key.'(\s?=)~iu',$newKey.'$1',$content);
echo $content;
output is NEW=I am listening.
But is does not change on a partial match
$content = 'LISTEN=I am listening.';
$key = 'TEN';
$new_key = 'NEW';
$content = preg_replace('~^'.$key.'(\s?=)~iu',$newKey.'$1',$content);
echo $content;
Output is LISTEN=I am listening.

Categories