I am using PHPs' strtr method to replace certain tokens/placeholders in a string. This works very well but now I'm trying to work out if all of my tokens were replaced.
The following example:
$trans = array(":hello" => "hi", ":hi" => "hello");
echo strtr(":hi all, I said :hello", $trans);
will output:
hello all, I said hi
Both tokens were replaced successfully but how do I check this. I can't search the output for occurrences of my delimiter ':' since the output string could contain valid ':' in the data.
Is there a way that I can escape these delimiters before doing the replace, then do a count on the unescaped delimiters to see if there were any token left unreplaced, and then finally unescape the escaped delimiters before returning?
NOTE: I cannot use str_replace, this method needs to be used.
I don't think strtr can help you here, it just replaces whatever it finds. What you seem to want is to figure out if there is a difference between the tokens in the array and in the string. For that, something like this should do:
preg_match_all('/:\w+/', $str, $matches);
if (array_diff($matches[0], array_keys($trans))) {
// the string has tokens that aren't in $trans
}
Related
I am trying to put quotes around the names of name-value pairs separated by commas. I use preg_replace and regex to achieve that. However, my pattern is not working properly.
$str="f1=1,f2='2',f3='a',f4=4,f5='5'";
$newstr=Preg_replace(/'(?.[^=]+)'/,"'$1'",$str);
I expected $newstr to come out like so:
'f1'=1,'f2'='2','f3'='a','f4'=4,'f5'='5'
But it doesn't and the qoutes don't contain the name.
What should the pattern be and how can I use the comma to get all of them correctly?
There are a few issues with your attempt:
PHP does not have a regex-literal syntax as in JavaScript, so starting the regex value with a forward slash is a syntax error. It should be a string, so start with a quote. Maybe you accidently swapped the slash and quote at the start and the end.
(?. is not valid. Maybe you intended (?:, but then there is no capture group and $1 is not a valid back reference. To have the capture group, you should not have (?., but just (.
[^=]+ could include substrings like 1,f2. There should be logic to not start matching while still inside a value (whether quoted or not).
I would suggest a regex where you match both parts around the = (both key and value), and then in the replacement, just reproduce the second part without change. This will ensure you don't accidently use anything in the value side for wrapping in quotes:
$newstr = preg_replace("/([^,=]+)=('[^']*'|[^,]*)/","'$1'=$2",$str);
Basically, match beginning of line or a comma (with negative capture) and then capture everything until a =
$reg = "/(?<=^|,)([^=]+)/";
$str = "f1=1,f2='2',f3='a',f4=4,f5='5'";
print_r(preg_replace($reg, "'$1'", $str));
// output:
// 'f1'=1,'f2'='2','f3'='a','f4'=4,'f5'='5'
This will also work, a different approach, but assuming there will be no comma in the values or names except the separators..
$newstr = preg_replace("/(.)(?==)|(?<=,|^)(.)/", "$1'$2", $str);
But I believe string and simple array operations will be faster as the regex is really getting complex and there are so many steps to get the characters.. Here is the same output but with array functions only.
$newstr = implode(",", array_map(function($element){ return "'". implode("'=", explode("=", $element)); }, explode(",", $str)));
RegEx is not always fast than string or array operations, but yes it can do complex things with little bit of code.
I have the following string:
feature name="osp"
I need to extract part of the strings out and put them into a new string. The word feature can change and the word inside quotes can change so I need to be able to capture any instance possible. The name=" " part is always the same. The result I need is:
feature osp
I need to filter out the name= and quotes from the string.
I've used this ^\w*\s to get the first feature part but can't figure out how to extract osp from the string using a regex. I've been looking here RegEx: Grabbing values between quotation marks but can't get a regex that combines both to get the result I need. I'm working in PHP so using preg-match at the moment. Can anyone help with this?
I'd go with
(\w+)\s+name\s*=\s*"([^"]*)
It's a little bit slower, but it allows for arbitrary number of spaces and it captures the first word correctly, even with Alexandru's test.
See it work here at regex101.
Regards
Try something like that:
preg_match('/(.+)name="(.+?)"/', $string, $matches);
echo $matches[1] . $matches[2];
An improved version of #vuryss
preg_match('/(.*?)name="(.*?)"/ims', $string, $matches);
echo $matches[1] . $matches[2];
I'm trying to retrieve the followed by count on my instagram page. I can't seem to get the Regex right and would very much appreciate some help.
Here's what I'm looking for:
y":{"count":
That's the beginning of the string, and I want the 4 numbers after that.
$string = preg_replace("{y"\"count":([0-9]+)\}","",$code);
Someone suggested this ^ but I can't get the formatting right...
You haven't posted your strings so it is a guess to what the regex should be... so I'll answer on why your codes fail.
preg_replace('"followed_by":{"count":\d')
This is very far from the correct preg_replace usage. You need to give it the replacement string and the string to search on. See http://php.net/manual/en/function.preg-replace.php
Your second usage:
$string = preg_replace(/^y":{"count[0-9]/","",$code);
Is closer but preg_replace is global so this is searching your whole file (or it would if not for the anchor) and will replace the found value with nothing. What your really want (I think) is to use preg_match.
$string = preg_match('/y":\{"count(\d{4})/"', $code, $match);
$counted = $match[1];
This presumes your regex was kind of correct already.
Per your update:
Demo: https://regex101.com/r/aR2iU2/1
$code = 'y":{"count:1234';
$string = preg_match('/y":\{"count:(\d{4})/', $code, $match);
$counted = $match[1];
echo $counted;
PHP Demo: https://eval.in/489436
I removed the ^ which requires the regex starts at the start of your string, escaped the { and made the\d be 4 characters long. The () is a capture group and stores whatever is found inside of it, in this case the 4 numbers.
Also if this isn't just for learning you should be prepared for this to stop working at some point as the service provider may change the format. The API is a safer route to go.
This regexp should capture value you're looking for in the first group:
\{"count":([0-9]+)\}
Use it with preg_match_all function to easily capture what you want into array (you're using preg_replace which isn't for retrieving data but for... well replacing it).
Your regexp isn't working because you didn't escaped curly brackets. And also you didn't put count quantifier (plus sign in my example) so it would only capture first digit anyway.
I'm new to preg_replace() and I've been trying to get this to work, I couldn't so StackOverflow is my last chance.
I have a string with a few of these:
('pm_IDHERE', 'NameHere');">
I want it to be replaced with nothing, so it would require 2 wildcards for NameHere and pm_IDHERE.
But I've tried it and failed myself, so could someone give me the right code please, and thanks :)
Update:
You are almost there, you just have to make the replacement an empty string and escape the parenthesis properly, otherwise they will be treated as capture group (which you don't need btw):
$str = preg_replace("#\('pm_.+?', '.*?'\);#si", "", $str);
You probably also don't need the modifiers s and i but that is up to you.
Old answer:
Probably str_replace() is sufficient:
$str = "Some string that contains pm_IDHERE and NameHere";
$str = str_replace(array('pm_IDHERE', 'NameHere'), '', $str);
If this is not what you mean and pm_IDHERE is actually something like pm_1564 then yes, you probably need regular expressions for that. But if NameHere has no actual pattern or structure, you cannot replace it with regular expression.
And you definitely have to explain better what kind of string you have and what kind of string you have want to replace.
I have strings in my application that users can send via a form, and they can optionally replace words in that string with replacements that they also specify. For example if one of my users entered this string:
I am a user string and I need to be parsed.
And chose to replace and with foo the resulting string should be:
I am a user string foo I need to be parsed.
I need to somehow find the starting position of what they want to replace, replace it with the word they want and then tie it all together.
Could anyone write this up or at least provide an algorithm? My PHP skills aren't really up to the task :(
Thanks. :)
$result = preg_replace('/\band\b/i', 'foo', $subject);
will find all occurences of and where it's a word on its own and replace it with foo. \b ensures that there is a word boundary before and after and.
use preg_replace. You don't need to think so hard about this though you will have to learn a little bit about regexes. :)
Read up on str_replace, or for more complex replacements on Regular Expressions and preg_replace.
Examples for both:
<?php
$str = 'I am a user string and I need to be parsed.';
echo str_replace( 'and', 'foo', $str ) . "\n";
echo preg_replace( '/and/', 'foo', $str ) . "\n";
?>
In response to the comments of this answer, note that both examples above will replace every occurrence of the search string (and), even when it happens to be within another word.
To take care of that you either have to add the word separators to the str_replace call (see the comment of an example), but this will get quite complicated when you want to take care of all common word separators (space, commas, dots, exclamation marks, question marks etc.).
An easier to way to fix this problem is to use the power of regular expressions and make sure, the actual search string is not found within another word. See Tim Pietzcker's example below for a possible solution.