I want to split string which contains braces
e.g.
string = "some-thing_text,text in rounded brackets(word first,word second),Text in curly brackets{some-text(some one,some two),some another},Text in square brackets[some text,some another{some like this(this1,this2)}]"
and output will be :
Array
(
[0] => some-thing_text
[1] => text in rounded brackets(word first,word second)
[2] => Text in curly brackets{some-text(some one,some two),some another}
[3] => Text in square brackets[some text,some another{some like this(this1,this2)}]
)
,(?![^{]*})(?![^(]*\))(?![^\[]*\])
You can use this.See demo.
https://regex101.com/r/lR1eC9/8
You may try this,
preg_split('~(?:\[.*?\]|\(.*?\)|\{.*?\})(*SKIP)(*F)|,~', $str);
(?:\[.*?\]|\(.*?\)|\{.*?\}) matches all the bracketed blocks.
(*SKIP)(*F) makes the previous match to fail.
, Now it matches comma from the remaining string.
DEMO
preg_split('~,(?![^{]*}|[^(]*\)|[^\[]*\])~', $string)
Related
$str = ({max_w} * {max_h} * {key|value}) / {key_1|value}
I have the above formula, I want to match the value with curly braces and which has a pipe separator. Right now the issue is it's giving me the values which have not pipe separator. I am new in regex so not have much idea about that. I tried below one
preg_match_all("^\{(|.*?|)\}^",$str, PREG_PATTERN_ORDER);
It gives below output
Array
(
[0] => key|value
[1] => max_w
[2] => max_h
[3] => key_1|value
)
Expected output
Array
(
[0] => key|value
[1] => key_1|value
)
Not sure about PHP. Here's the general regex that will do this.
{([^{}]*\|[^{}]*)}
Here is the demo.
You can use
(?<={)[^}]*\|[^}]*(?=})
For the given string the two matches are shown by the pointy characters:
({max_w} * {max_h} * {key|value}) / {key_1|value}
^^^^^^^^^ ^^^^^^^^^^^
Demo
(?<={) is a positive lookbehind. Arguably, the positive lookahead (?=}) is not be needed if it is known that all braces appear in matching, non-overlapping pairs.
The pattern \{(|.*?|)\} has 2 alternations | that can be omitted as the alternatives on the left and right of it are not really useful.
That leaves \{(.*?)} where the . can match any char including a pipe char, and therefore does not make sure that it is matched in between.
You can use a pattern that does not crosses matching a curly or a pipe char to match a single pipe in between.
{\K[^{}|]*\|[^{}|]*(?=})
{ Match opening {
\K Forget what is matches until now
[^{}|]* Match any char except the listed
\| Match a | char
[^{}|]* Match any char except the listed
(?=}) Assert a closing } to the right
Regex demo | PHP demo
$str = "({max_w} * {max_h} * {key|value}) / {key_1|value}";
$pattern = "/{\K[^{}|]*\|[^{}|]*(?=})/";
preg_match_all($pattern, $str, $matches);
print_r($matches[0]);
Output
Array
(
[0] => key|value
[1] => key_1|value
)
Or using a capture group:
{([^{}|]*\|[^{}|]*)}
Regex demo
Given string $str = 'aa {{asd}} bla {{{888 999}} {555} 777 uiii {{-i {{qw{er}}';
Need get all occurrences between closest opening-closing double curly brackets.
Desirable result:
asd
888 999
qw{er
If try: preg_match_all('#\{\{(.*?)\}\}#', $str, $matches);
Current output:
asd
{888 999
-i {{qw{er
though, these occurrences aren't between closest double curly brackets.
Question is: what is appropriate pattern for this?
You can use this pattern:
\{\{(?!\{)((?:(?!\{\{).)*?)\}\}
The trick here is to use a negative lookahead like (?!\{\{) to avoid matching nested brackets.
\{\{ # match {{
(?!\{) # assert the next character isn't another {
(
(?: # as few times as necessary...
(?!\{\{). # match the next character as long as there is no {{
)*?
)
\}\} # match }}
Regex demo
Regex: (?<=\{{2})(?!\{)[\s\w\{]+(?=\}\})
(?=\}\}) Should contain double curly braces ahead
(?<=\{{2}) Should contain curly braces behind
(?!\{) should not contain curly braces one curly brace behind two matched
PHP code:
$str = 'aa {{asd}} bla {{{888 999}} {555} 777 uiii {{-i {{qw{er}}';
preg_match_all("/(?<=\{{2})(?!\{)[\s\w\{]+(?=\}\})/",$str,$matches);
print_r($matches);
Output:
Array
(
[0] => Array
(
[0] => asd
[1] => 888 999
[2] => qw{er
)
)
In PHP, I need to split a string by ":" characters without a leading "*".
This is what using explode() does:
$string = "1*:2:3*:4";
explode(":", $string);
output: array("1*", "2", "3*", "4")
However the output I need is:
output: array("1*:2", "3*:4")
How would I achieve the desired output?
You're probably looking for preg_match_all() rather than explode(), as you are attempting a more complex split than explode() itself can handle. preg_match_all() will allow you to gather all of the parts of a string that match a specific pattern, expressed using a regular expression. The pattern you are looking for is something along the lines of:
anything except : followed by *: followed by anything but :
So, try this instead:
preg_match_all('/[^:]+\*:[^:]+/', $string, $matches);
print_r($matches);
Which will output something like:
Array
(
[0] => Array
(
[0] => 1*:2
[1] => 3*:4
)
)
Which you should be able to use in much the same way that you would use the results of explode() even if there is the added dimension in the array (it divides the matches into 'groups', and all your results match against the whole expression or the first (0th) group).
$str = '1*:2:3*:4';
$res = preg_split('~(?<!\*):~',$str);
print_r($res);
will output
Array
(
[0] => 1*:2
[1] => 3*:4
)
The pattern basically says:
split by [a colon that is not lead by an asterisk]
This is a really simple problem, but I couldn't find a solution anywhere.
I'm try to use preg_match or preg_match_all to obtain a string from within parentheses, but without the parentheses.
So far, my expression looks like this:
\([A-Za-z0-9 ]+\)
and returns the following result:
3(hollow highlight) 928-129 (<- original string)
(hollow highlight) (<- result)
What i want is the string within parentheses, but without the parentheses. It would look like this:
hollow highlight
I could probably replace the parentheses afterwards with str_replace or something, but that doesn't seem to be a very elegant solution to me.
What do I have to add, so the parentheses aren't included in the result?
Thanks for your help, you guys are great! :)
try:
preg_match('/\((.*?)\)/', $s, $a);
output:
Array
(
[0] => (hollow highlight)
[1] => hollow highlight
)
You just need to add capturing parenthesis, in addition to your escaped parenthesis.
<?php
$in = "hello (world), my name (is andrew) and my number is (845) 235-0184";
preg_match_all('/\(([A-Za-z0-9 ]+?)\)/', $in, $out);
print_r($out[1]);
?>
This outputs:
Array ( [0] => world [1] => is andrew [2] => 845 )
I want to extract the url from the background css property "url('/img/hw (11).jpg') no-repeat". I tried:
$re = '/url\(([\'\"]?.*\.[png|jpg|jpeg|gif][\'\"]?)\)/i';
$text = "url('/img/hw (11).jpg')";
preg_match_all($re, $text, $matches);
print_r($matches);
and it gives me :
Array
(
[0] => Array
(
)
[1] => Array
(
)
)
Here is the correct regex. The ".*" in the middle of your regex is too greedy. Also, try replacing the square brackets with paranthesis. Also note that since you are using single quotes around the string that you do not need to escape the double quotes.
$re = '/url\(([\'"]?.[^\'"]*\.(png|jpg|jpeg|gif)[\'"]?)\)/i';
Try:
/url\(([\'\"]?.*\.(png|jpg|jpeg|gif)[\'\"]?)\)/i
Instead. The square brackets do a character-by-character comparison rather than the or comparison you're looking for.
I think the probably lies in this part [png|jpg|jpeg|gif]. It's supposed to match only single characters.
You should do this instead :
/url\([\'\"]?(.*\.(jpg|png|jpeg|gif)[\'\"]?)\)/