Replacing a string using preg_match - php

I'm having trouble using preg_match to find and replace a string. The string of interest is:
<span style="font-size:0.6em">EXPIRATION DATE: 04/30/2011</span>
I need to target and replace the date, "04/30/2011" with a different date. Can someone throw me a bone a give me the regular expression to match this pattern using preg_match in PHP? I also need it to match in such a way that it only replaces up to the first closing span and not closing span tags later in the code, e.g.:
<span style="font-size:0.6em">EXPIRATION DATE: 04/30/2011</span><span class="hello"></span>
I'm not versed in regex, and although I've spent the last hour trying to learn enough to make this work, I'm utterly failing. Thanks so much!
EDIT: As you can see this has gotten me exhausted. I did mean preg_replace, not preg_match.

If you're after a replacement, consider using preg_replace(), something like
preg_replace('#(\d{2})/(\d{2})/(\d{4})#', '<new date>', $string);

How about this:
$toBeFoundPattern = '/([0-9][0-9])\/([0-9][0-9])\/([0-9][0-9][0-9][0-9])/';
$toBeReplacedPattern = '$2.$1.$3';
$inString = '<span style="font-size:0.6em">EXPIRATION DATE: 04/30/2011</span>';
// Will convert from US date format 04/30/2011 to european format 30.04.2011
echo preg_replace( $toBeFoundPattern, $toBeReplacedPattern, $inString );
and prints
EXPIRATION DATE: 30.04.2011
Patterns always begin and end with identical so called delimiter characters. Often the character / is used.
$1 references the string, which matched the first string matched by ([0-9][0-9]), $2 references be (...) and $3 the four letters matched by the last (...).
[...] matched a single character, which is one of those listed inside the brackets. E.g. [a-z] matches all lower case letters.
To use the special meaning character / inside of a pattern, you need to escape it by \ to make it be the literal slash character.
Update: Using {..} as pointed out below is shorthand for repeated patterns.

Regex should be:
(0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])[- /.](19|20)\d\d
If you want to only match one instance, this is OK. For multiple instances, use preg_match_all instead. Taken from http://www.regular-expressions.info/regexbuddy/datemmddyyyy.html.
Edit: are you looking to just search and replace inside a PHP script or do you want to do some javascript live replacement?

Related

PHP preg_replace pattern only seems to work if its wrong?

I have a string that looks like this
../Clean_Smarty_Projekt/tpl/templates_c\.
../Clean_Smarty_Projekt/tpl/templates_c\..
I want to replace ../, \. and \.. with a regulare expression.
Before, I did this like this:
$result = str_replace(array("../","\..","\."),"",$str);
And there it (pattern) has to be in this order because changing it makes the output a little buggy. So I decided to use a regular expression.
Now I came up with this pattern
$result = preg_replace('/(\.\.\/)|(\\[\.]{1,2})/',"",$str);
What actually returns only empty strings...
Reason: (\\[\.]{1,2})
In Regex101 its all ok. (Took me a couple of minutes to realize that I don't need the /g in preg_replace)
If I use this pattern in preg_replace I have to do (\\\\[\.]{1,2}) to get it to work. But that's obviously wrong because im not searching for two slashes.
Of course I know the escaping rulse (escaping slashes).
Why doesn't this match correctly ?
I suggest you to use a different php delimiter. Within the / delimiter, you need to use three \\\ or four \\\\ backslashes to match a single backslash.
$string = '../Clean_Smarty_Projekt/tpl/templates_c\.'."\n".'../Clean_Smarty_Projekt/tpl/templates_c\..';
echo preg_replace('~\.\./|\\\.{1,2}~', '', $string)
Output:
Clean_Smarty_Projekt/tpl/templates_c
Clean_Smarty_Projekt/tpl/templates_c

How would i write a regular expression to check for a string of text surrounded by equal signs?

How would i use regular expressions to check for characters within the following string of text:
=== logo ===
I tried to use a regex tester but could come up with the correct expression for i've tried this:
/^[=]{3}$/
I want search within a string find where the text starts with 3 equal signs.
Find a string or any other characters within the equal signs.
Find 3 more equal signs.. ending the expression.
Thanks in advance.
Try using this regex:
/===[^=]+===/
If you want to capture the text, surround it in parentheses:
/===([^=]+)===/
Here's the fiddle: http://jsfiddle.net/jufXA/
If you might have equal signs in your text (but less than 3, obviously) you should instead match everything lazily (which is a tad slower):
/===(.+?)===/
Here's the fiddle: http://jsfiddle.net/jufXA/1/
How about as simple as...
/===(.+?)===/
For example:
$test = "here's ===something special===, like ===this=one===";
preg_match_all('/===(.+?)===/', $test, $matches);
var_dump($matches[1]);
Laziness is kinda virtue here: the regex engine won't advance past the first 'closing delimiter ==='. Without ?, however, you need to use negated character classes (but then again, what about ===something=like=this===?).
I prefer:
/([=]{3})\s*(.+?)\s*\1/.
This puts the text markup (three equal signs) in the beginning and then just uses a back reference for the end. It also trims your text of spaces, which is what you probably want.

Regular expression doesn't quite work

I have created a Regular Expression (using php) below; which must match ALL terms within the given string that contains only a-z0-9, ., _ and -.
My expression is: '~(?:\(|\s{0,},\s{0,})([a-z0-9._-]+)(?:\s{0,},\s{0,}|\))$~i'.
My target string is: ('word', word.2, a_word, another-word).
Expected terms in the results are: word.2, a_word, another-word.
I am currently getting: another-word.
My Goal
I am detecting a MySQL function from my target string, this works fine. I then want all of the fields from within that target string. It's for my own ORM.
I suppose there could be a situation where by further parenthesis are included inside this expression.
From what I can tell, you have a list of comma-separated terms and wish to find only the ones which satisfy [a-z0-9._\-]+. If so, this should be correct (it returns the correct results for your example at least):
'~(?<=[,(])\\s*([a-z0-9._-]+)\\s*(?=[,)])~i'
The main issues were:
$ at the end, which was anchoring the query to the end of the string
When matching all you continue from the end of the previous match - this means that if you match a comma/close parenthesis at the end of one match it's not there at match at the beginning of the next one. I've solved this with a lookbehind ((?<=...) and a lookahead ((?=...)
Your backslashes need to be double escaped since the first one may be stripped by PHP when parsing the string.
EDIT: Since you said in a comment that some of the terms may be strings that contain commas you will first want to run your input through this:
$input = preg_replace('~(\'([^\']+|(?<=\\\\)\')+\'|"([^"]+|(?<=\\\\)")+")~', '"STRING"', $input);
which should replace all strings with '"STRING"', which will work fine for matching the other regex.
Maybe using of regex is overkill. In this kind of text you can just remove parenthesis and explode string by comma.

PHP Regex: match text urls until space or end of string

This is the text sample:
$text = "asd dasjfd fdsfsd http://11111.com/asdasd/?s=423%423%2F gfsdf http://22222.com/asdasd/?s=423%423%2F
asdfggasd http://3333333.com/asdasd/?s=423%423%2F";
This is my regex pattern:
preg_match_all( "#http:\/\/(.*?)[\s|\n]#is", $text, $m );
That match the first two urls, but how do I match the last one? I tried adding [\s|\n|$] but that will also only match the first two urls.
Don't try to match \n (there's no line break after all!) and instead use $ (which will match to the end of the string).
Edit:
I'd love to hear why my initial idea doesn't work, so in case you know it, let me know. I'd guess because [] tries to match one character, while end of line isn't one? :)
This one will work:
preg_match_all('#http://(\S+)#is', $text, $m);
Note that you don't have to escape the / due to them not being the delimiting character, but you'd have to escape the \ as you're using double quotes (so the string is parsed). Instead I used single quotes for this.
I'm not familar with PHP, so I don't have the exact syntax, but maybe this will give you something to try. the [] means a character class so |$ will literally look for a $. I think what you'll need is another look ahead so something like this:
#http:\/\/(.*)(?=(\s|$))
I apologize if this is way off, but maybe it will give you another angle to try.
See What is the best regular expression to check if a string is a valid URL?
It has some very long regular expressions that will match all urls.

How can I check if a string EXACTLY matches a regex pattern?

I'm working on a registration script for my client's product sales website.
I'm currently working on a reference ID input area, and I want to make sure that the reference ID is within the correct parameters of the payment method
The Reference ID will look something like this: XXXXX-XXXXX-XXXXX
I'm trying to use this RegEx pattern to match it: /(\w+){5}-(\w+){5}-(\w+){5}/
This matches it perfectly, but it also matches XXXXX-XXXXX-XXXXXXXXXX
Or at least it finds a match in there. I want it to make sure the entire string matches. I'm not too familiar with RegEx
How can I do this?
You need to use start and finish anchors. Alternatively, if you don't need to capture those groups, you can omit the parenthesis.
Also, the +{5} means match more than once exactly 5 times. I believe you didn't want that so I dropped the +.
/^\w{5}-\w{5}-\w{5}\z/
Also, I used \z so your string doesn't match "abcde-12345-edcba\n".
Use ^ and $ to match the start and end of the input string, respectively.
Also note that your use of + was superfluous, as (\w+){5} means "a word character, at least once, times five" which means it can match at least five times. You probably meant (\w){5} (or just \w{5} if you don't need the backreference; I'll assume in my example that you do).
/^(\w){5}-(\w){5}-(\w){5}$/
put the regular expression in between ^ and $ to match the whole string and check if it matches anything
example:
/^(\w+){5}-(\w+){5}-(\w+){5}$/
Try
/^([\w]{5,5})-([\w]{5,5})-([\w]{5,5})$/i
There are several online regex tester out there, I work with this one before I code.
Enclose it in "^" and "$" thus:
/^(\w+){5}-(\w+){5}-(\w+){5}$/
You need ^ to match the start of the string and $ to match the end:
/^\w{5}-\w{5}-\w{5}$/
Note that (\w+){5} is incorrect because that means five repetitions of \w+, but that in turn means "one or more word characters".
/^(\w){5}-(\w){5}-(\w){5}$/
You need to explicitly say that you want the pattern to start at the beginning of the string and end at it's ending.
You can improve it: /^((\w){5}-){2}(\w){5}$/ ; this way, you can easily modify the number of elements your serial number might have.
Use ^ and $ to mark the start and end of the regex string:
/^\w{5}-\w{5}-\w{5}$/
http://www.regular-expressions.info/anchors.html
In preg, \b marks word boundaries. So you could try with something like
/\b(\w+){5}-(\w+){5}-(\w+){5}\b/

Categories