Regex to find function call php - php

I need the regex to find function calls in strings in php, I have tried to search here on stackoverflow but none of the ones i've tried worked.
this pattern: ^.*([\w][\(].*[\)])
This will match: functionone(fgfg) but also functionone(fgfg) dhgfghfgh functiontwo() as one match. Not 2 separate matches (as in functionone(fgfg) and functiontwo().
I don't know how to write it but I think this is what I need.
1. Any string, followed by (
2. Any string followed by )
And then it should stop, not continue. Any regex-gurus that can help me out?

I see 5 issues with your regex
If you want to match 2 functions in the same row, don't use the anchor ^, this will anchor the regex to the start of the string.
You then don't need .* at the start maybe more something like \w+ (I am not sure what the spec of a function name in PHP is)
if there is only one entry in a character class (and its not a negated one), you don't need the character class
The quantifier between the brackets needs to be a lazy one (followed by a ?). So after this 4 points your regex would look something like
\w+\(.*?\)
Is a regex really the right tool for this job?

Don't use regexp for this... use PHP's built-in tokenizer

A function signature is not a regular language. As such, you cannot use a regular expression to match a function signature. Your current regex will match signatures that are NOT valid function signatures.
What I would suggest you use is the PHP tokenizer.

Related

How to remove backpath/parentpath from the URL?

Input:
http://foo/bar/baz/../../qux/
Desired Output:
http://foo/qux/
This can be achieved using regular expression (unless someone can suggest a more efficient alternative).
If it was a forward look-up, it would be as simple as:
/\.\.\/[^\/]+/
Though I am not familiar with with how to make a backward look up for the first "/" (ie. not doing /[a-z0-9-_]+\/\.\./).
One of the solutions I thought of is to use strrev then apply forward look up regex (first example) and then do strrev. Though I am sure there is a more efficient way.
Not the clearest question I've ever seen, but if I understand what you're asking, I think you only need to switch around what you have like this:
/[^\/]+/\.\./
...then replace that with a /
Do that until no replacements are made and you should have what you want
EDIT
Your attempt seems to try to match a forward slash / and two dots \.\. followed by a slash / (or \/ - they should both match the same thing), then one or more non-slash characters[^/]+, terminated by a slash /. Flipping it around, you want to find a slash followed by one or more non-slash characters and a terminating slash, then two dots and a final slash.
You may be confused into thinking that the regex engine parses and consumes things as it goes (so you wouldn't want to consume a directory name that is not followed by the correct number of dots), but that's not how it typically works - a regex engine matches the entire expression before it replaces or returns anything. So, you can have two dots followed by a directory name, or a directory name followed by two dots - it doesn't make a difference to the engine.
If your attempt is using the slash-enclosed Perl-style syntax, then you would of course need to use \/ for any slashes you're trying to match such as the middle one, but I would also recommend matching and replacing the enclosing slashes in the url as well: I think the PHP would be something like
preg_replace('/\/[^\/]+\/\.\.\//', '/', $input)
(??)
Technically what do you want is replace segments of '/path1/path2/../../' by '/' what is needed to do that is match 'pathx/'^n'../'^n that is definetly NOT a regular expression (Context Free Lenguaje) ... but most of Regex libraries supports some non regular lenguajes and can (with a lot of effort) manage those kind of lenguajes.
An easy way to solve it is stay in Regular Expressions and cycle several times, replacing '/[^./]+/../' by ''
if you still to do it in a single step, Lookahead and grouping is needed, but it will be hard to write it, (I'm not so used on, but I will try)
EDIT:
I've found the solution in only 1 REGEX... but should use PCRE Regex
([^/.]+/(?1)?\.\./)
I've based my solution on the folowing link:
Match a^n b^n c^n (e.g. "aaabbbccc") using regular expressions (PCRE)
(note that dots are "forbidden" in the first section, you cannot have path.1/path.2/ if you whant to is quite more complex because you should admit them but forbid '../' as valid in the first section
this sub expression is for admiting the path names like 'path1/'
[^/.]+/
this sub expression is for admiting the double dots.
\.\./
you can test the regexp in
https://www.debuggex.com/
(remember to set it in PCRE mode)
Here is a working copy:
https://eval.in/52675

PHP regular expression : match the closest one

I have a string like this
<div><span style="">toto</span> some character <span>toto2</span></div>
My regex:
/(<span .*>)(.*)(<\/span>)/
I used preg_match and it returns the entire string
<span style="">toto</span> some character <span>toto2</span>
I want it returns:
<span style="">toto</span>
and
<span>toto2</span>
What do I need to do to achieve this? Thanks.
How about this:
/(<span[^>]*>)(.*?)(<\/span>)/
Check the docs here at PHP preg_match Repetition:
By default, the quantifiers are "greedy", that is, they match as much as possible
and
However, if a quantifier is followed by a question mark, then it becomes lazy, and instead matches the minimum number of times possible
Even though I guess all previous answers are correct, I just want to add that as you only want to capture the whole expressions (i.e. from to ) you don't have to capture eveything inside the regexp with ()
The following does what you expect without capturing additional expressions
/(<span\w*[^>]*>[^<]*<\/span>)/
(tested on http://rubular.com/)
EDIT : of course there might be some differences between PHP and ruby regexp implementations, but the idea is the same :)

regex and preg_replace_callback

I have a problem with a regular expression.
I'm working with tokens and I have to parse a text like this:
Just some random text
#IT=AB|First statement# #xxxx=xxx|First statement|Second statement#
More text
I use preg_replace_callback since I have to use the first statement or the second one, depending on the first expression is true or not; it's a sort of IF...ELSE... statement.
What I expect are 2 elements like this:
#IT=AB|First statement#
#xxxx=xxx|First statement|Second statement#
So I can start manipulating them inside my callback function.
I tried with this regex /#.*#/, but i get the entire string, it's not parsed into elements.
How can I achieve that? I'm sorry but regex aren't my thing :(
The quantifier * is greedy by default. So a .* will match as much as it can and as a result it'll match a # as well. To fix this you can make the * non-greedy by adding a ? after it. Now a .*? will try to much as little as it can.
/#.*?#/
or you can look for only non # characters between two #:
/#[^#]*#/

What Regex for this?

I'm trying to learn regular expression, because I can't do without them.
So, this is a list of different dimension patterns (for products to sale) :
40x30x75
46x38x23-27
Ø30H30
Ø25-18H27
So, what pattern to use to find each kind of dimensions ?
For example, now, I'm using this to find this kind of pattern 40x30x75, but it not works :
if(preg_match("#^[0-9][x][0-9][x][0-9]#", $dimension))
echo "ok"
Could you help me ?
Try the following regex:
(^[0-9]+x[0-9]+x[0-9]+$)|(^[0-9]+x[0-9]+x[0-9]+-[0-9]+$)|(^Ø[0-9]+H[0-9]+$)|(^Ø[0-9]+-[0-9]+H[0-9]+$)
So:
if (preg_match("/(^[0-9]+x[0-9]+x[0-9]+$)|(^[0-9]+x[0-9]+x[0-9]+-[0-9]+$)|(^Ø[0-9]+H[0-9]+$)|(^Ø[0-9]+-[0-9]+H[0-9]+$)/", $dimension))
echo "ok";
It probably can be simplified even more, maybe someone would want to have a go at that?
By the way, did you know about a website called RegExr it allows you to test your regular expessions, it has been very useful to me whenever I work with regex's.
Your regex is missing quantifiers, add a + sign behind the character classes in question to singal you're looking for one or more matches:
if(preg_match("#^[0-9]+x[0-9]+x[0-9]+#", $dimension))
echo "ok"
By default it's looking for one character of the class only. Single characters do not need the character class (albeit it was not wrong). See the x'es in the example above.
Your regex should be:
^[0-9]{2}x[0-9]{2}x[0-9]{2}$
[0-9] means a single character which is between 0 and 9. So, you either need to have two of those, or use a quantifier thing like {2}. Instead of [0-9] you could also use \d, meaning any digit. So, you could for example write:
^\d\dx\d\dx\d\d$
Tip: If you can't do without regular expressions, want to learn it and have an easier life, I can recommend you get RegexBuddy. Bought it for myself when I just got started, and it has helped me a lot.
This will validate the first two:
^[0-9]+x[0-9]+x[0-9]+-?[0-9]*$

Regex equals condition except for certain condition

I have written the following Regex in PHP for use within preg_replace().
/\b\S*(.com|.net|.us|.biz|.org|.info|.xxx|.mx|.ca|.fr|.in|.cn|.hk|.ng|.pr|.ph|.tv|.ru|.ly|.de|.my|.ir)\S*\b/i
This regex removes all URLs from a string pretty effectively this far (though I am sure I can write a better one). I need to be able to add an exclusion though from a specific domain. So the pseudo code will look like this:
IF string contains: .com or .net or. biz etc... and does not contain: foo.com THEN execute condition.
Any idea on how to do this?
Just add a negative lookahead assertion:
/(?<=\s|^)(?!\S*foo\.com)\S*\.(com|net|us|biz|org|info|xxx|mx|ca|fr|in|cn|hk|ng|pr|ph|tv|ru|ly|de|my|ir)\S*\b/im
Also, remember that you need to escape the dot - and that you can move it outside the alternation since each of the alternatives starts with a dot.
Use preg_replace_callback instead.
Let your callback decide whether to replace.
It can give more flexibility if the requirements become too complicated for a simple regex.

Categories