preg_match and preg_replace in php - php

I have a task to find and replace words starting and ending with "#".
Example - my string will look like:
Put your hands up in the air for #performer1# , Put your hands up in the air for #event#.
What I expect as a output is:
Put your hands up in the air for #performer1# , Put your hands up in the air for #event#.
I have no idea about regular expressions in php, and I'm a beginner, can someone help?

As you already suggested, the preg_replace function should do the trick. What you now need is a regular expression like this
$string = "Put your hands up in the air for #performer#, ...";
$pattern = "/#(\w+)#/";
$replacement = '<strong>$1</strong>';
$new_string = preg_replace($pattern, $replacement, $string);
The magic bit is the $pattern variable where you specify what to look for. If you put parenthesis around something, you can reference the actual contents in the $replacement variable.
The \w+ basically says: match as many characters as possible (and at least one) that are either a-z, A-Z, 0-9 or _.
The PHP PCRE Pattern Syntax can give you some more hints about how to use regular expressions.

Related

How to get a number from a html source page?

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.

Preg match a string to find all encounters of -> using regular expressions

I'm having a small technical difficulty with a regular expression, I'm trying to look at a string, let's say we have this string:
$string = "error->400";
And another string:
$string = "error->debug->warning";
As an example, I'm basically trying to do a preg_match() that returns true on any instances of -> within it.
This is my attempt but I don't understand why it doesn't work:
preg_match("/^[->]*$/", $string);
Is there a general rule for custom characters that i'm generally missing?
Thanks.
Right now, ^[->]*$ matches any number of "-" or ">" characters, from the beginning to end. You must use a group, not a character class, and anchors are not necessary. Use this to check if "->" is present in the $string:
preg_match("/(->)/", $string);
Have a look at the example.

PHP preg_match_all not matching properly

I am trying to get some data off of a website source code. What I am trying to do is get everything after /collections/(whatever that follows here). My pattern matched "most" of what I am looking for. The problem occurs when my preg_match_all gets to a pattern with the "&", at which point it will simply read to the point of "&" and stop reading the remainder. Here is my script:
$homepage = file_get_contents('http://www.harrisfarm.com.au/');
$pattern = '/collections([\w-&\/]*)/i';
preg_match_all($pattern, $processedHomePage, $collections);
print_r($collections);
Notice that when printing like this, things after the "&" are ignored, meaning it will get me this:
/collections/seafood/Shellfish-&
But when I am pattern matching on one string such as below:
$subject = 'a href="/collections/organic/Pantry/sickmonster/grandma" <a href="/collections/seafood/Shellfish-&-Crustaceans">Oysters, Shellfish & Crustaceans';
it gets me everything I want:
/collections/seafood/Shellfish-&-Crustaceans
So I wonder... why is this happening? I am really stumped here.
There is no problem with the provided code when you use $homepage instead of $processedHomePage in preg_match_all.
BTW:
You should escape the minus sign in squared brackets (or write it at the beginning or end of the expression in squared brackets), but surprisingly it makes no difference in your case:
$pattern = '/collections([-\w&/]*)/i';
See http://php.net/manual/regexp.reference.meta.php for further information.
try this:
$re = "/\\/collections([\\w\\-\\&\\/;]*)/mi";
$str = "<a href=\"/collections/seafood/Shellfish-&-Crustaceans\">Oysters, Shellfish & Crustaceans';\n<a href=\"/collections/seafood/Shellfish-&-Crustaceans\">Oysters,collections Shellfish & Crustaceans';";
preg_match_all($re, $str, $matches);
live demo
your update code
$homepage = file_get_contents('http://www.harrisfarm.com.au/');
$pattern = "/\\/collections([\\w\\-\\&\\/;]*)/mi";
preg_match_all($pattern, $homepage, $collections);
print_r($collections);
I figured out what the problem is - maybe this will help others later.
I had tried to use htmlspecialchars() to convert the url http://www.harrisfarm.com.au/ and then read it in as a string. This converted some special characters like & and some other things, into something with many characters.
The conversion of & turns it into & which has a ;, and that's not in my regular expression. Since ; is not part of regular expression, the regex stopped matching at that point.

Replace from one custom string to another custom string

How can I replace a string starting with 'a' and ending with 'z'?
basically I want to be able to do the same thing as str_replace but be indifferent to the values in between two strings in a 'haystack'.
Is there a built in function for this? If not, how would i go about efficiently making a function that accomplishes it?
That can be done with Regular Expression (RegEx for short).
Here is a simple example:
$string = 'coolAfrackZInLife';
$replacement = 'Stuff';
$result = preg_replace('/A.*Z/', $replacement, $string);
echo $result;
The above example will return coolStuffInLife
A little explanation on the givven RegEx /A.*Z/:
- The slashes indicate the beginning and end of the Regex;
- A and Z are the start and end characters between which you need to replace;
- . matches any single charecter
- * Zero or more of the given character (in our case - all of them)
- You can optionally want to use + instead of * which will match only if there is something in between
Take a look at Rubular.com for a simple way to test your RegExs. It also provides short RegEx reference
$string = "I really want to replace aFGHJKz with booo";
$new_string = preg_replace('/a[a-zA-z]+z/', 'boo', $string);
echo $new_string;
Be wary of the regex, are you wanting to find the first z or last z? Is it only letters that can be between? Alphanumeric? There are various scenarios you'd need to explain before I could expand on the regex.
use preg_replace so you can use regex patterns.

Replacing HTML attributes using a regex in PHP

OK,I know that I should use a DOM parser, but this is to stub out some code that's a proof of concept for a later feature, so I want to quickly get some functionality on a limited set of test code.
I'm trying to strip the width and height attributes of chunks HTML, in other words, replace
width="number" height="number"
with a blank string.
The function I'm trying to write looks like this at the moment:
function remove_img_dimensions($string,$iphone) {
$pattern = "width=\"[0-9]*\"";
$string = preg_replace($pattern, "", $string);
$pattern = "height=\"[0-9]*\"";
$string = preg_replace($pattern, "", $string);
return $string;
}
But that doesn't work.
How do I make that work?
PHP is unique among the major languages in that, although regexes are specified in the form of string literals like in Python, Java and C#, you also have to use regex delimiters like in Perl, JavaScript and Ruby.
Be aware, too, that you can use single-quotes instead of double-quotes to reduce the need to escape characters like double-quotes and backslashes. It's a good habit to get into, because the escaping rules for double-quoted strings can be surprising.
Finally, you can combine your two replacements into one by means of a simple alternation:
$pattern = '/(width|height)="[0-9]*"/i';
Your pattern needs the start/end pattern character. Like this:
$pattern = "/height=\"[0-9]*\"/";
$string = preg_replace($pattern, "", $string);
"/" is the usual character, but most characters would work ("|pattern|","#pattern#",whatever).
I think you're missing the parentheses (which can be //, || or various other pairs of characters) that need to surround a regular expression in the string. Try changing your $pattern assignments to this form:
$pattern = "/width=\"[0-9]*\"/";
...if you want to be able to do a case-insensitive comparison, add an 'i' at the end of the string, thus:
$pattern = "/width=\"[0-9]*\"/i";
Hope this helps!
David

Categories