How can I match repeating pattern in this string? - regex

I am trying to find the matches of the contains query in the following ODATA filter:
Name eq 'test' and contains(Address,'fdgr345') and contains(Description,'test')
I am using the regex:
(contains\s*\(([\w]+)\,\'([\s\w\s]+\')\))+.
However, this regex returns only the first match i.e.
contains(Address,'fdgr345').
How can I get all the occurrences of the contains(..., '...') pattern?

You need to pass some form of global flag in order to tell regex to capture all instances of your regex.
Typically this can look something like this:
/REGEX/flags
or in your case:
/contains\s*\(([\w]+)\,\'([\s\w\s]+\')\)/g
where the g-flag denotes global. Additionally I removed the outer ()+ since this is trying to match repeated patterns like so:
TEXTnStuff contains(Address,'fdgr345')contains(Address,'abc123') MORETEXT

Related

Only Match String if Text Does Not Contain Another String

I have the following use case. I need a Regex pattern to only match a line, if part of the string does not contain a different string. Here is an example:
<androidx.constraintlayout.widget.Barrier
android:id="#+id/barrier6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"/>
So here I want to match android:layout_marginStart="12dp" so that I can replace with:
android:layout_marginStart="12dp"
android:layout_marginLeft="12dp"
I have worked this one out and I can use the following regex to do it:
Find: (.*)android:layout_marginStart="(.*)"
Replace: $1android:layout_marginStart="$2"\n$1android:layout_marginLeft="$2"
What I can't do is conditionally match. I do not want to match if this xml object already contains the android:layout_marginLeft attribute.
In regex, if you want to check to make sure a string is not coming up after the part you wish to match, you can use a negative lookahead.
In this example, you want to match something, but only if the string layout_marginLeft is not coming up later. You can do that, but throwing layout_marginLeft into a negative lookahead, like this:
(?:(?!layout_marginLeft).)*
Now, when you combine that with what you actually want to match your regex would look something like this:
(android:layout_marginStart="(.*?)")(?:(?!layout_marginLeft).)*(?=/>)
And then your replacement string would look like this:
\1\n\t\tandroid:layout_marginLeft="\2"
So, the replacement stuff works the same way, it's just that you are telling it not to do a replacement on anything that already contains layout_marginLeft.
Here is a demo

Regex to match the string until character occured, unless it's enclosed within quotes

Assuming a QueryString that looks like: $filter=Name eq "Demo"&project=10
I would like to use groups to get the value of the $filter.
This can be done with the following regex:
\$filter=(?P<group>[^&]*)
However, when the filter looks like $filter=Name eq "De&mo"&project=10 the Regex does not work anymore because it matches the & sign that enclosed within ".
How shoud this regex be adapted so that the full $filter is retrieved?
Kind regards
You can use this regex to match and consule all quoted string in the query parameter $filter:
\$filter=((?:[^"&]*"[^"]*")*[^"&]*)
RegEx Demo

Erlang regular expression must match entire string

I am trying to write some code to validate a list of colon separated k/v pairs in erlang. I can get the following expression to match a single pair.
re:run(Tag, "^([a-zA-Z0-9]{1,50}:[^:][ ]?[a-zA-Z0-9\\.\\-\\_\\+]{1,50})")
So, if I pass a tag of key:value it matches as expected. But, I need it to NOT match if I pass something like key:value:123. It appears that what is happening is that re returns {match, Match} if any part of the string matches. However, I need it to only return match if the ENTIRE string matches. Is there a way to do this in erlang? I read-over the docs at http://www.erlang.org/doc/man/re.html and tried a few things with options but have yet to figure it out.
Just add a $ on the end to match the full line:
^([a-zA-Z0-9]{1,50}:[^:][ ]?[a-zA-Z0-9\.\-\_\+]{1,50})$
^ here
This is a feature of regular expressions, not Erlang specifically.

How to match a string that does not end in a certain substring?

how can I write regular expression that dose not contain some string at the end.
in my project,all classes that their names dont end with some string such as "controller" and "map" should inherit from a base class. how can I do this using regular expression ?
but using both
public*.class[a-zA-Z]*(?<!controller|map)$
public*.class*.(?<!controller)$
there isnt any match case!!!
Do a search for all filenames matching this:
(?<!controller|map|anythingelse)$
(Remove the |anythingelse if no other keywords, or append other keywords similarly.)
If you can't use negative lookbehinds (the (?<!..) bit), do a search for filenames that do not match this:
(?:controller|map)$
And if that still doesn't work (might not in some IDEs), remove the ?: part and it probably will - that just makes it a non-capturing group, but the difference here is fairly insignificant.
If you're using something where the full string must match, then you can just prefix either of the above with ^.* to do that.
Update:
In response to this:
but using both
public*.class[a-zA-Z]*(?<!controller|map)$
public*.class*.(?<!controller)$
there isnt any match case!!!
Not quite sure what you're attempting with the public/class stuff there, so try this:
public.*class.*(?<!controller|map)$`
The . is a regex char that means "anything except newline", and the * means zero or more times.
If this isn't what you're after, edit the question with more details.
Depending on your regex implementation, you might be able to use a lookbehind for this task. This would look like
(?<!SomeText)$
This matches any lines NOT having "SomeText" at their end. If you cannot use that, the expression
^(?!.*SomeText$).*$
matches any non-empty lines not ending with "SomeText" as well.
You could write a regex that contains two groups, one consists of one or more characters before controller or map, the other contains controller or map and is optional.
^(.+)(controller|map)?$
With that you may match your string and if there is a group() method in the regex API you use, if group(2) is empty, the string does not contain controller or map.
Check if the name does not match [a-zA-Z]*controller or [a-zA-Z]*map.
finally I did it in this way
public.*class.*[^(controller|map|spec)]$
it worked

Multiple results from one subgroup

I have this string:
<own:egna attribute1="1" attribute2="2">test</own:egna>
I want to catch all attributes with a regexp.
This regexp matches one attribute: (\s+attribute\d=['"][^'"]+['"])
But why is it that appending a + like ``(\s+attribute\d=['"][^'"]+['"])+` actually only returns the last matched attribute and not all of them?
How would you change this to return all attributes in separate groups?
I'm actually having more regexp around this, so using functions such as python's findall and equivalents won't do.
The short answer is you can't - only the last group is accessible. The Python docs state this explicitly:
If a group matches multiple times, only the last match is accessible [...]
You'll have to use some language features:
In PHP, there's preg_match_all that returns all matches.
In other languages, you'll have to do this manually: add the g modifier to the regex and loop over it. Perl, for example, will manage a string position and return the next match in $1 each time a /([...])/g pattern is matched.
Also take a look at Capturing a repeated group.