If I had a string like <start_delim>asdf<end_delim> and I wanted to take an alphanumeric string between the delimiters and reverse it using regexes, how would I go about doing this?
My natural instinct was to use something like preg_replace("<start_delim>([a-zA-Z0-9]+)<end_delim>", strrev($1), $str), but for obvious reasons, that didn't work.
You'll have to use preg_replace_callback
$str = "<start_delim>asdf<end_delim>";
function my_callback($m) {
return $m[1].strrev($m[2]).$m[3];
}
echo preg_replace_callback("/(<start_delim>)([a-zA-Z0-9]+)(<end_delim>)/", 'my_callback' , $str);
http://codepad.org/xP2arFZk
Similar to previous solutions, but using a lambda:
$str = "<start_delim>asdf<end_delim>";
$result = preg_replace_callback('/<start_delim>([a-zA-Z0-9]+)<end_delim>/', function($matches) {
return strrev($matches[1]);
}, $str);
echo "$result\n";
Somebody pointed out in a comment it'd be better not to use the /e modifier, but
if possible, that would work. Almost exactly as you thought:
echo preg_replace('|<start_delim>([^<^]+)<end_delim>|e', 'strrev("$1")', $str);
Regards
rbo
Related
I have two functions in PHP, trimmer($string,$number) and toUrl($string). I want to trim the urls extracted with toUrl(), to 20 characters for example. from https://www.youtube.com/watch?v=HU3GZTNIZ6M to https://www.youtube.com/wa...
function trimmer($string,$number) {
$string = substr ($string, 0, $number);
return $string."...";
}
function toUrl($string) {
$regex="/[^\W ]+[^\s]+[.]+[^\" ]+[^\W ]+/i";
$string= preg_replace($regex, "<a href='\\0'>".trimmer("\\0",20)."</a>",$string);
return $string;
}
But the problem is that the value of the match return \\0 not a variable like $url which could be easily trimmed with the function trimmer().
The Question is how do I apply substr() to \\0 something like this substr("\\0",0,20)?
What you want is preg_replace_callback:
function _toUrl_callback($m) {
return "" . trimmer($m[0], 20) ."";
}
function toUrl($string) {
$regex = "/[^\W ]+[^\s]+[.]+[^\" ]+[^\W ]+/i";
$string = preg_replace_callback($regex, "_toUrl_callback", $string);
return $string;
}
Also note that (side notes wrt your question):
You have a syntax error, '$regex' is not going to work (they don't replace var names in single-quoted strings)
You may want to look for better regexps to match URLs, you'll find plenty of them with a quick search
You may want to run through htmlspecialchars() your matches (mainly problems with "&", but that depends how you escape the rest of the string.
EDIT: Made it more PHP 4 friendly, requested by the asker.
I have strings like this
[Ljava.lang.String;
[Ldummy.class.Here;
[Lanother.unknown.Class;
What regex should i use to replace [L and ; with <span>,[]</span>
And make it look like this
<span>java.lang.String[]</span>
<span>dummy.class.Here[]</span>
<span>another.unknown.Class[]</span>
What i want is to make java array class string representation more human friendly
I've heard about $1 or something like that, but i couldn't find more information as i don't know what is it
$strings = "[Ljava.lang.String;
[Ldummy.class.Here;
[Lanother.unknown.Class;";
$strings = preg_replace('/\[L([A-Za-z\.]+);/', '<span>$1[]</span>', $strings);
echo $strings;
Output:
$ php foo.php
<span>java.lang.String[]</span>
<span>dummy.class.Here[]</span>
<span>another.unknown.Class[]</span>
If you want to use plain old PHP for this rather than a regex, here is a simple snippet that will do exactly what you need - and you can modify it without having to sort through regex that makes little sense to you:
<?php
$stringArray=array(
'[Ljava.lang.String;',
'[Ldummy.class.Here;',
'[Lanother.unknown.Class;'
);
foreach($stringArray as $val)
{
$output=$val;
if($val[0].$val[1]=='[L')
{
$output="<span>".substr($val,2);
}
if(substr($output,-1)==';')
{
$output=substr($output,0,strlen($output)-1).'</span>';
}
echo $output.'<br>';
}
?>
Output:
<span>java.lang.String</span>
<span>dummy.class.Here</span>
<span>another.unknown.Class</span>
This should do it:
$new_content = preg_replace('#^\[L(.*);\s*$#m', '<span>$1[]</span>', $content);
Demo here: http://sandbox.onlinephpfunctions.com/code/8f0de08b5ba0882db2d98d99cdd961b9aebab074
You can use this:
$result = preg_replace('~\[L([^;]+);~', '<span>$1[]</span>', $txt);
where [^;]+ matches all that is not a ";"
Is there a simple way to use ltrim() to remove a single instance of a match instead of all matches?
I'm looping through array of strings and I'd like to remove the first, and only first, match (vowels in this case):
ltrim($value, "aeiouyAEIOUY");
With default behavior the string aardvark or Aardvark would be trimmed to be "rdvark". I'd like result to be "ardvark".
I'm not bound to ltrim by any means but it seemed the closest built-in PHP function. It would be nice of ltrim and rtrim had an optional parameter "limit", just saying... :)
Just use preg replace it has a limit option
eg
$value = preg_replace('/^[aeiouy]/i', '', $value, 1);
Regular expressions is probably overkill, but:
$value = preg_replace('/^[aeiouy]/i', '', $value);
Note the i makes it case-insensitive.
You can't use ltrim to do this for the reasons you say, nor can you use str_replace (which also has no limit). I think it's easiest just to use a regex:
$value = preg_replace('/^[aeiouy]/i', '', $value);
However if you really don't want to do that, you can use a substring, but you would have to check the position of any of those strings in the string in a loop as there is no php function that does such a check that I know of.
You can use the preg_replace function:
<?php
$value = preg_replace('/^[aeiouy]/i', '', $value);
?>
There are several way you can go about doing what you are looking to do.
Perhaps most straightforward would be a regular expression replacement like this:
$pattern = '/^[aeiouy]{1}/i';
$result = preg_replace($pattern, '', $original_string);
This is probably the most efficient way (so ignore my regular expressions answer):
if (strpos('aeiouyAEIOUY', $value[0]) !== false) $value = substr($value, 1);
Or,
if (stripos('aeiouy', $value[0]) !== false) $value = substr($value, 1);
Basically from a database I am getting data that is formatted like this nameofproject101 Now this could continue to increase so eventually it could be nameofproject1001 my question is how can I trim off the number and just get the name of the project. I thought about using substr but since I dont know the length always I cant really do that. Since the numbers differ I dont think I can use str_replace is there any way to accomplish this?
It sounds like something is way off about your database scheme. You should probably try to do refactor/normalize your scheme.
But in the meantime, you can use rtrim() to trim all numbers off of the right side.
$val = rtrim($val, '0123456789');
Examples
Input Output
nameofproject1001 nameofproject
nameofproject nameofproject
n4me0fproj3ct1001 n4me0fproj3ct
for string like, project12V123, It is better to do this
$text = `project12V123`;
$text = preg_replace('/([\w]+)([^0-9])([0-9])+$/', '$1$2', $text);
Will return:
Project12V
or use rtrim:
$text = rtrim($text,'0123456789');
You should definitely use regular expressions:
$fullname = "nameofproject101";
preg_match("/([a-z]+)([0-9]+)/i", $fullname, $matches);
$name = $matches[1];
$number = $matches[2];
echo "'$fullname' is '$name' followed by '$number'";
preg_replace('/[^a-z]/i', '', $string);
I'm not too great at preg_match yet and I was wondering if someone could give me a hand.
I have an array of values e.g. array("black*", "blue", "red", "grey*") I need to find the values with a * at the end then return the word before it.
I believe preg_match() is the best way of doing it but I'm open to suggestions.
Thanks in advanced!
If you must use a regex...
$words = array_map(function($word) {
return preg_replace('/\*\z/', '', $word);
}, $arr);
CodePad.
...but you're probably better off not using regex and using something like...
$words = array_map(function($word) {
return rtrim($word, '*');
}, $arr);
CodePad.
If you want to return only the words which have a trailing *, try something like this first...
$words = preg_grep('/\*\z/', $arr);
CodePad.
The only disadvantage with this (as mentioned in the comments) is PHP will iterate twice over the array. You can simply use a foreach loop to do both of these in one loop if you wish.
Also, it is worth mentioning anonymous functions are a PHP 5.3 thing. You can still most of this code, just separate the functions into their own named functions and pass a reference to them.
If you always have an array like that (i.e. no complex strings, just word*), you really shouldn't use regular expressions, it's an overkill.
Use string functions, like strpos for searching and str_replace or rtrim for removing *.
If you don't need fancy replacing rules (like regular expressions), you should always use this function instead of preg_replace().
— from str_replace manual
Don't need to use preg_match for this - simple char lookup on the string will work:
$words = array('red*', 'grey', 'white', 'green*');
$return = array();
foreach ($words as $word) {
if ($word[strlen($word) - 1] === '*') {
$return[] = substr($word, 0, -1);
}
}
var_dump($return);