preg_match on special characters - php

I’m trying to make a preg_match in my PHP code, but I can't seem to get it to work.
I have these 3 tags
{$success url='http://www.domain.localhost/form-success'}
{$error url='http://www.domain.localhost/form-error'}
{$button title='send form'}
How can I get my preg_match to accept what I’m trying to do?
I’m trying to get {$button(*)} out to my match path, and the same I want to do with the 2 others {$success(*)} and {$error(*)}
Now I think it should look like this
preg_match("/\{\$button(.+?)}/s", $content, $match);
But it still isn’t working, so I hope other people can help me here.

\$ already means "literal $" in PHP strings, so when put in a regex it just means "end of string".
Try \\\$ instead.

I think the correct regex to retrieve the 'button' tag should be : \{\$button([^\}]*)\}
You can try your expression on http://regexpal.com/
So with php :
preg_match("/\{\$button([^\}]*)\}/s", $content, $match );

You need to escape the closing } and need to use preg_match_all to match all the lines.
Try this regex:
preg_match('/\{\$(?:success|error|button)\s+([^}]+)\}/i', $content, $match );
Working Demo: http://ideone.com/fKq5L2
OUTPUT:
Array
(
[0] => {$success url='http://www.domain.localhost/form-success'}
[1] => {$error url='http://www.domain.localhost/form-error'}
[2] => {$button title='send form'}
)

Related

Parse string with regex and get desired output

I want to parse this string
[[delay-4]]Welcome! [[delay-2]]Do you have some questions for us?[[delay-1]] Please fill input field!
I need to get something like this:
[
[0] => '[[delay-4]]Welcome!',
[1] => '[[delay-2]]Do you have some questions for us?',
[2] => '[[delay-1]] Please fill input field!
];
String can also be something like this (without [[delay-4]] on beginning):
Welcome! [[delay-2]]Do you have some questions for us?[[delay-1]] Please fill input field!
Expected output should be something like this:
[
[0] => 'Welcome!',
[1] => '[[delay-2]]Do you have some questions for us?',
[2] => '[[delay-1]] Please fill input field!
];
I tried with this regex (https://regex101.com/r/Eqztl1/1/)
(?:\[\[delay-\d+]])?([\w \\,?!.##$%^&*()|`\]~\-='\"{}]+)
But I have problem with that regex if someone writes just one [ in text, regex fails and if I include [ to match I got wrong results.
Can anyone help me with this?
Two simpler actions might be the route to get the result:
$result = preg_replace('/\s*(\[\[delay-\d+]])/i', "\n$1", $subject);
$result = preg_split('/\r?\n/i', $result, -1, PREG_SPLIT_NO_EMPTY);
Can be seen running here:
https://ideone.com/Z5tZI3
and here:
https://ideone.com/vnSNYI
This assumes that newline characters don't have special meaning and are OK to split on.
UPDATE: As noted in the comments below it's possible with a single split.
$result = preg_split('/(?=\[\[delay-\d+]])/i', $subject, -1, PREG_SPLIT_NO_EMPTY);
But there are possible issues with zero-length matches and regular expressions, you would have to do your own research on that.
In your pattern (?:[[delay-\d+]])?([\w \,?!.##$%^&*()|`]~-='\"{}]+)
there is no opening [ in the character class. The problem is that if you add it, you get as you say wrong results.
That is because after matching after matching delay, the character class in the next part which now contains the [ can match the rest of the characters including those of the delay part.
What you could do is to add [ and make the match non greedy in combination with a positive lookahead to assert either the next match for the delay part or the end of the string to also match the last instance.
If you are not using the capturing group and only want the result you can omit it.
(?:\[\[delay-\d+]])?[\w \\,?!.##$%^&*()|`[\]~\-='\"{}]+?(?=\[\[delay-\d+]]|$)
Regex demo | Php demo
You can do that without regex too.
Explode on [[ and loop the array. If the start of the item is "delay" then add [[
$str = '[[delay-4]]Welcome! [[delay-2]]Do you have some questions for us?[[delay-1]] Please fill input field!';
$arr = array_filter(explode("[[", $str));
foreach($arr as &$val){
if(substr($val,0,5) == "delay") $val = "[[" . $val;
}
var_dump($arr);
https://3v4l.org/sIui1

php preg_match replace result duplicate

I am a newbie in preg_match patterns, so I would be glad if someone could help me for next situation:
I need to replace those string:
[popup="about"]about me[/popup]
to
<a href="#PopupAbout" data-plugin-options='{"type":"inline", preloader: false}'>about me</a>
I have tried with $pattern = '/\[popup="(.*?)"\](.*?)\[\/popup\]/'; but it does not give me expected result, it give duplicated results. And how can I replace it all in a simple way!
Regards!
How about:
$str = preg_replace('~\[popup="about"\](.+?)\[/popup\]'~,
"<a href=\"#PopupAbout\" data-plugin-options='{\"type\":\"inline\", preloader: false}'>$1</a>",
$str);
Try this:
preg_match("/\[popup="(.*)"\](.*?)\[\/popup\]/", $input_line, $output_array);
I get this result:
Array
(
[0] => [popup="about"]about me[/popup]
[1] => about
[2] => about me
)
You can test it online here: http://www.phpliveregex.com/

Removing parentheses from a string

I'd like to remove all parentheses from a set of strings running through a loop. The best way that I've seen this done is with the use of preg_replace(). However, I am having a hard time understanding the pattern parameter.
The following is the loop
$coords= explode (')(', $this->input->post('hide'));
foreach ($coords as $row)
{
$row = trim(preg_replace('/\*\([^)]*\)/', '', $row));
$row = explode(',',$row);
$lat = $row[0];
$lng = $row[1];
}
And this is the value of 'hide'.
(1.4956873362063747, 103.875732421875)(1.4862491569669245, 103.85856628417969)(1.4773257504016037, 103.87968063354492)
That pattern is wrong as far as i know. i got it from another thread, i tried to read about patterns but couldn't get it. I am rather short on time so I posted this here while also searching for other ways in other parts of the net. Can someone please supply me with the correct pattern for what I am trying to do? Or is there an easier way of doing this?
EDIT: Ah, just got how preg_replace() works. Apparently I misunderstood how it worked, thanks for the info.
I see you actually want to extract all the coordinates
If so, better use preg_match_all:
$ php -r '
preg_match_all("~\(([\d\.]+), ?([\d\.]+)\)~", "(654,654)(654.321, 654.12)", $matches, PREG_SET_ORDER);
print_r($matches);
'
Array
(
[0] => Array
(
[0] => (654,654)
[1] => 654
[2] => 654
)
[1] => Array
(
[0] => (654.321, 654.12)
[1] => 654.321
[2] => 654.12
)
)
I don't understand entirely why you would need preg_replace. explode() removes the delimiters, so all you have to do is remove the opening and closing parantheses on the first and last string respectively. You can use substr() for that.
Get first and last elements of array:
$first = reset($array);
$last = end($array);
Hope that helps.
"And this is the value of $coords."
If $coords is a string, your foreach makes no sense. If that string is your input, then:
$coords= explode (')(', $this->input->post('hide'));
This line removes the inner parentheses from your string, so your $coords array will be:
(1.4956873362063747, 103.875732421875
1.4862491569669245, 103.85856628417969
1.4773257504016037, 103.87968063354492)
The pattern parameter accepts a regular expression. The function returns a new string where all parts of the original that match the regex are replaced by the second argument, i.e. replacement
How about just using preg_replace on the original string?
preg_replace('#[()]#',"",$this->input->post('hide'))
To dissect your current regex, you are matching:
an asterisk character,
followed by an opening parenthesis,
followed by zero or more instances of
any character but a closing parenthesis
followed by a closing parenthesis
Of course, this will never match, since exploding the string removed the closing and opening parentheses from the chunks.

stuck in regular expression i dont know if it is even possible or not using php preg_match_all

i have a file out of which i want a specific data below is the sample data
moduleHelper.addModule('REC');
moduleHelper.addModule('TOP');
What i want is
anything.anything('x');i.e.
moduleHelper.addModule('');
The above is what i want to be returned .
i just dont want the 'x' part exclusive of single quote.
i tried by my self and wrote a regex which is below.
/(.*)\.(.*)\(\'[^.*]\'\)/mi
it gives me nothing according to the PCRE manual the ^ inside the [ ] does negation ??
It could be done with preg_replace_callback if you feel like figuring out how all that backreferencing works, but i think this is a bit easier:
// the regex
$regex = "/(?P<FIRST>.+)?\.(?P<SECOND>.+)\('(?P<PARAM>.+)?\'\)?/mi";
$subject = <<<EOB
moduleHelper.addModule('REC');
moduleHelper.addModule('TOP');
EOB;
$matches = array();
$numberOfMatches = preg_match_all($regex, $subject, $matches, PREG_SET_ORDER);
$results = array();
foreach($matches as $match)
{
array_push($results, sprintf("%s.%s('')", $match['FIRST'], $match['SECOND']));
}
print_r($results);
// result:
Array
(
[0] => moduleHelper.addModule('')
[1] => moduleHelper.addModule('')
)
Try using the following
/^([^.]+)\.([^\(]+)/
If ^ is the first character in [ ] then it negates the other characters in the set. Where [ab] accepts either a or b, [^ab] accepts any character that is not a nor b.
Also I'm not sure what you want. You state that you do not want the 'x', but what exactly do you want?
It does do negation. [^.*], in this case, means "get on character that is not . or *. I think you want below, but I can't totally tell.
preg_match_all( "/(\w+\.\w+)(?=\([\"']\w+[\"']\);)/i", $string, $matches);
Try this one:
/([^.]*)\.([^.]*)\(.*\)/

Why is this regular expression not working?

Content of 1.txt:
Image" href="images/product_images/original_images/9961_1.jpg" rel="disable-zoom:false; disable-expand: false"><img src="im
Code that does not work:
<?php
$pattern = '/(images\/product_images\/original_images\/)(.*)(\.jpg)/i';
$result = file_get_contents("1.txt");
preg_match($pattern,$result,$match);
echo "<h3>Preg_match Pattern test:</h3><br><br><pre>";
print_r($match);
echo "</pre>";
?>
I expect this result:
Array
(
[0] => images/product_images/original_images/9961_1.jpg
[1] => images/product_images/original_images/
[2] => 9961_1
[3] => .jpg
)
But i take this-like:
Array
(
[0] => images/product_images/original_images/9961_1.jpg" rel="disable-zoom:false; disable-expand: false">
[1] => images/product_images/original_images/
[2] => 9961_1.jpg" rel="disable-zoom:false; disable-expand: false">
)
I'n tired of trying from a million combinations of this regexp. I dunno what's wrong. Please and thanks a lot!
Make it ungreedy:
$pattern = '/(images\/product_images\/original_images\/)(.*?)(\.jpg)/i';
Remember that Regular Expressions are greedy. Your second capture (.*) says to match any character except the new line (unless in mutliline mode). So it is probably capturing the rest of the line.
You can make it ungreedy as suggested by Wrikken. But I like to ensure I am capturing what I want. In your case, it looks like the value of the href attribute. So really I want at least 1 character, can't be a quote, followed by the jpg extension:
$pattern = '/(images\/product_images\/original_images\/)([^'"]+)(\.jpg)/i';
Here's the basic regex:
href="((.*/)(.*?)(.jpg))"
Do not parse HTML with regex.
Do not parse HTML with regex.
Do not parse HTML with regex.

Categories