Regex Replace [ with -> depending on a condition - php

I'm looking for a regex that could replace all "[" with an "->" but only when it's not followed by "]".
And replace at the same time all of the "]" with nothing, but only when they are not next to an "["
So in other word "test[hi][]" will be become "test->hi[]"
Thank you ;)
I really have no clue how to do that ;)

I've made the assumptions that what exist between the brackets follows PHP variable naming conventions (i.e. letters, digits, underscores) and your code is valid (e.g. no $test['five]).
echo preg_replace('/\[[\'"]?(\w+)[\'"]?\]/', '->\1', $input);
This should handle:
test[one]
test['two']
test["three"]
But not:
test[$four]

No regexp needed!
strtr($str, array('[]'=>'[]','['=>'->',']'=>''))
$ cat 1.php
<?php
echo strtr('[hi][]', array('[]'=>'[]','['=>'->',']'=>''));
$ php 1.php
->hi[]

replace this regex \[(\w+)\] with -> + match group 1

This should do. It uses
\[ # match a [
( # match group
[^\]]+ # match everything but a ] one or more times
) # close match group
\] # match ]
to match anything between brackets
$replaced = preg_replace("/\[([^\]]+)\]/", "->$1", $string);

Related

PHP regex url matching

I have some example:
mysite.com/tag/HD+Wallpaper //match
mysite.com/tag/HD+Wallpaper/ //match
mysite.com/tag/HD+Wallpaper?page= //match
mysite.com/tag/HD+Wallpaper/?page= //match
mysite.com/tag/HD+Wallpaper/sdadasdas //not match
with "HD+Wallpaper" is a param
i try :
^tag/(.+?)(|\/|\?(.*?))$i
How can i fix it ? TY
You could try following regex
tag\/.*?(?=\/|\?|$)
Demo
Note:
In the demo, I added backslash \ to escape /
This regex should work for you:
tag\/([^\/]*?)(?=\/$|\/\?|\?|$)
Demo
You might use
tag/[^/\s]+(?:/(?:\?.*)?)?$
Explanation
tag/ Match literally (perhaps /tag/ or \btag would be more specific)
[^/\s]+ Match 1+ occurrences of any char except / or a whitespace char
(?: Non capture group
/(?:\?.*)? Match / followed by an optional part to match ? and the rest of the string
)? Close group and make it optional
$ End of string
Regex demo

PHP Regex find + alter + replace within each tag

I am new to regex if this is indeed what I need.
The string might include :
[name* your-name ]
[email* your-main-email some_thing]
etc
Amateur logic :
Search string for '['
get substring between this and next ']'
extract hyphenated word (probably find first word between first and next space)
Replace substring with hyphenated word
Repeat with all remaining tags
To hopefully produce :
[your-name]
[your-main-email]
etc
Or am I off target with method?
Many thanks
Try this code
$str = '[name* your-name ] [email* your-main-email some_thing]';
$str = preg_replace("/\[[^\s]+\s+([^\]\s]+)\s+[^\]]*\]/", "[$1]", $str);
echo $str;
Regex explanation:
/ Delimiter
\[ Match starting square bracket
[^\s]+ Match one or more non-space character
\s+ Match one or more space
( Start capturing group
[^\]\s]+ Match one or more character that is not space and not ]
) End capturing group
\s+ Match one or more space
[^\]]* Match zero or more character that is not ]
\] Match closing square bracket
/ Delimiter
Edit
To do replace when last space is missing i.e. [name* your-name] then use following regex
/\[[^\s]+\s+([^\]\s]+)[^\]]*\]/

Another regex: square brackets

I have something like: word[val1|val2|val3] . Need a regex to capture both: word and val1|val2|val3
Another sample: leader[77]
Result: Need a regex to capture both: leader and 77
This is what I have so far: ^(.*\[)(.*) and it gives me: array[0]=word[val1|val2|val3];
array[1]=word[
array[2]=val1|val2|val3]
array[1] is needed but without [
array[2] is needed but without ]
Any ideas? - Thank you
For the either one you can use \w*(\[.*\])
\w* match any word character [a-zA-Z0-9_]
Quantifier: * Between zero and unlimited times
\[ matches the character [ literally
.* matches any character (except newline)
\] matches the character ] literally
EDIT: I kept hammering away to get rid of the brackets and came up with (\w*)\[([^][]*)]
EDIT: Which I now see Wiktor suggested in comments before I got back with mine.
You can use
([^][]+)\[([^][]*)]
Here is the regex demo
Explanation:
([^][]+) - Group 1 matching one or more chars other than ] and [
\[ - a literal [
([^][]*) - Group 2 capturing 0+ chars other than [ and ]
] - a literal ].
See IDEONE demo:
$re = '~([^][]+)\[([^][]*)]~';
$str = "word[val1|val2|val3]";
preg_match($re, $str, $matches);
echo $matches[1]. "\n" . $matches[2];

How to multiple regexes into one regex

Hi I have 3 regex preg_match in 1 if..
I want to know if it's possible to mix 3 regex in 1?
this is my if with 3 regex :
if(!preg_match("#\s#",$file) && !preg_match("#\.\.\/#",$file) && (preg_match_all("#/#",$file,$match)==1)):
(I want: no "space" , no "../" and only 1 "/")
thanks for your help.
EDIT
add the needed in list point (more readable):
no "space"
no "../"
1 "/"
It's quite simple. Let's start step by step crafting this regex:
First of all, let's use anchors to define begin&end of string: ^$
I want: no "space", we've got \S which matches a non-white space character: ^\S+$
no "../", let's add a negative lookahead ^(?!.*[.][.]/)\S+$, note that we don't need to escape the dot inside a character class. As for the forwardslash, we'll use different delimiters
one optional "/", we could add a negative lookahead that prevents 2 forwardslashes ^(?!(?:.*/){2})(?!.*[.][.]/)\S+$
Let's define the delimiters and add the s modifier to match newlines with .: ~^(?!(?:.*/){2})(?!.*[.][.]/)\S+$~s and here you go with an online demo
You can use:
if (preg_match('~^(?!.*?(?: |\.\./))(?!(.*?/){2}).*$~', $file) {
...
}
Working Demo
Why not this:
if (preg_match('~((?>[^\s/.]++|\.(?!\./))*)/?(?1)\z~A', $str))
echo 'OK';
details:
~
( # capture group 1
(?>
[^\s./]++ # all that is not a space, a dot or a slash
| # OR
\.(?!\./) # a dot not followed by another dot and a slash
)*
)
/? # optional /
(?1) # repeat the capture group 1
\z # anchor for end of the string
~A # anchored pattern
Note: if you want to exclude the empty string, two possibilities:
if (preg_match('~(?=.)((?>[^\s/.]++|\.(?!\./))*)/?(?1)\z~A', $str))
or
if (preg_match('~((?>[^\s/.]++|\.(?!\./))*)/?(?1)\z~A', $str, $m) && $m)
You cannot merge the three because you have a match_all.
I would replace preg_match_all by substr_count, because pattern is static, so it should be faster.
if(!preg_match("#\s|\.\./#",$file) && (substr_count($file,'/')<=1))
Edit: replaced ==1 by <=1 for / being optional
Edit2: We do not loose too much readability by just merging the two negative patterns

What defines a regex section to be replaced in preg_replace()?

I just started with PHP regular expressions. I understand how to read and write them (I need my book though because I haven't memorized any pattern symbols). I really want to use RegExp for BB Code on my site, using preg_replace.
I understand the parameters, but what I don't understand is what defines what is to be replaced in the pattern? What I have so far:
preg_replace('/(\[url=http:\/\/.*\])/','$2',"[url=http://google.com]");
Now, I know it's probably not the best "security" wise, I just want to get something to work. I match the entire string... so I get a link that looks like mysite/[url=http://google.com].
I read over the PHP manual on it, but I still have a headache trying to absorb and comprehend something:
What defines what is replaced in the string because of the pattern?
What TELLS me what my $1 and $2 and so on are?
I don't even know what they are called. Could someone explain this to me?
The same replacement without errors:
$BBlink = '[url=http://google.com]';
$pattern = '~\[url=(http://[^] ]+)]~';
$replacement = '$1';
$result = preg_replace($pattern, $replacement, $BBlink);
explanations:
1) pattern
~ # pattern delimiter
\[ # literal opening square bracket
url=
( # first capturing group
http://
[^] ]+ # all characters that are not ] or a space one or more times
) # close the capturing group
] # literal closing square bracket
~ # pattern delimiter
2) replacement
$1 refer to the first capturing group
Alternative: http://www.php.net/manual/en/function.bbcode-create.php, see the first example.

Categories