I'm having some trouble understanding why a regular expression is not working. I'm searching for the phrase #Test(groups = {"broken"}), and I'm not able to find it with this expression:
#Test\(groups = {"broken"}\)
However, this expression yields results:
#Test\(.*groups = {"broken"}\)
Why is this happening? I can't see why the first expression would not work, but I understand why the second one does.
\( is used for capture in vim since it does not use extended/"magic" regexen by default. If you want to search for a literal paren, use (.
The second expression works because .* matches (.
If you want to search for literal text, just prepend \V to the search pattern; then, only the backslash has special meaning and must be escaped:
/\V#Test(groups = {"broken"})
In contrast to most other regular expression dialects, many Vim atoms need to be prefixed with \ to be non-literal. To make Vim's patterns look more like Perl's, you can prepend \v; then, (...) do capture grouping (as you've expected), and you need to escape \( to match literal parentheses.
Related
how to write a regular expression to match the below string :
name(abc1) or number(param9) or listget(12jtxgh)
I want to match the string enclosed in brackets only if it is prepended by name or number or listget.
I tried to this :
r'((.*?))'
and if my expression looks like below :
(name(foo) & number(bar)) - listget(baz)
then it starts matching (name(foo) also. I want my regex to extract only foo, bar and baz from the above expression as it is appended by name, number, listget.
I have to write regex in this form only #r'regex'
The following regular expression should do the trick:
(?:listget|name|number)\(([^)]+)\)
You can try a working demo by visiting this link. As others pointed out, parenthesis must be escaped in order to match their literal, otherwise they are being used by the regex for different purposes (like capturing groups).
In regex brackets are special symbols used for grouping. To match them you have to use an escape character \ like this \(.
For NOT matching a symbol ex. brackets:
[^)]
should be used. Where you don't need the escape character.
For finding an alternative you should use the pipe character | surrounded by brackets. Example:
(mary|john)
For NOT catching a group in a result match inside the the brackets you should start with ?:
I'm trying to do a project wide search and replace
from:
drivers[i].findElement(By.id("elementID")).click();
to:
findAndClick(driver[i], "elementID", true)
The issue is the elementID can be anything so I'm trying to wildcard search and replace with what's in the wildcard?
You'll need to use .+? instead of * here since this uses regular expressions.
In regular expressions a dot . means "any character", the plus + means "one or more times", and the question mark ? after this means "try to match this as few as possible times" - which is useful so it won't keep matching past your quote marks
edit
To be clear though, you have to make a valid regex, which means you'll need to escape your parenthesis, dots, etc.
Here's the full solution
Find: drivers\[i\]\.findElement\(By\.id\("(.+?)"\)\)\.click\(\);
replace with: findAndClick(driver[i], "$1", true)
Note the added unescaped parentheses in there around the "wildcard" (.+) this creates a capture group in a regex, which is what translates to $1 in the replacement since it's the 1st capture group.
This is my first time trying to use a regex for deletion.
The regex:
/net=.+\.net/
as shown here matches a string that starts with net= some random characters and ends with .net
However, when using it in vim:
:g/net=.+\.net/d
I simply get Pattern not found: net=.+\.net
I am guessing that vim uses a slightly different format, or do I need to escape the characters =, . and + ?
:help pattern is your friend. In your case, you need to escape + or prefix your whole pattern with \v to turn it “verymagic”.
Do not escape =, it would turn it into the same thing as {0,1} in some regexp engine, namely a greedy optional atom matcher.
What regular expression in Vim will match all
characters up to no. in the below sting?
foo, bar, and baz, no. 13, qux
In other words the match must be foo, bar, and baz,
I'm new with regular expressions, did my research here on Stack
Overflow, and one suggestion is .+?(?= no.). But it seems to work
only with the regular (perl?) flavour of regular expressions, not in
Vim.
Please, help.
Maybe there's a simpler solution to what I'm trying to achieve. My ultimate goal is to put foo, bar, and baz in curly brackets, and I planned to to a global substitution command involving regular expressions.
this regex in vim should do
.*\zeno
e.g. you do this on your line:
s/.*\zeno//
that line would be changed into:
no. 13, qux
EDIT
just saw your "ultimate goal", you can just use the regex:
:s/.*\zeno/{&}
if you don't want to wrap the comma:
:s/.*\ze, no/{&}
My ultimate goal is to put 'foo, bar, and baz' in curly brackets
You could try
:s/\v(.*)(, no\.)/{\1}\2/
This should do:
.*\( no[.]\)\#=
In words, all characters up to the set of characters matching " no.". The match look ahead, \#=, performs the check for " no.".
All answers given so far are wrong to me, because they perform a greedy match. In a line where there are several occurrences of “no”, they will match up to the last one:
YES YES YES YES no YES YES no YES
^^^^^^^^^^^^^^^^^^^^^^^^^^^
However, the purpose when matching everything up to some string is often to stop at the first occurrence:
YES YES YES YES no YES YES no YES
^^^^^^^^^^^^^^^^
For this purpose, use a non‐greedy regular expression, such as:
.\{-}\(no\)\#=
\{-} is the non‐greedy alternative to the multiplier * (see :help non-greedy). \#= is a positive look‐ahead, it will check that “no” follows but will not include it in the match (see :help /\#= ).
As a side note, a common scenario for “matching everything up to some string” is to match an expression with opening and closing delimiters. Examples:
C‐style string literals "string literal";
C++‐style comments // comment\n (whose closing delimiter is the newline character);
regular expressions /regex/.
In many such cases, the closing delimiter may in fact appear escaped inside the expression to be matched. For instance:
A C‐style string literal may contain the double‐quote character, in which case it must appear escaped as in \".
In a C++ comment, a newline character preceeded by a backslash is ignored, with the side effect that the comment continues on the following line.
A regular expression may contain a slash; in an overly simplistic approach to the syntax of regular expressions, we may assume that all such occurrences are escaped as in \/ (this is not true, for example /[abc/]/ is also a valid Vim regex which matches any character among “a”, “b”, “c”, “/”).
Hence, we must refine our regular expression so that it does not stop on escaped occurrences of the closing delimiter.
Let’s start with the wrong regular expression that matches anything between a starting delimiter “start” and a closing delimiter “stop” (which are not included in the match, thanks to the positive look‐behind \#<= and the positive look‐ahead \#= ):
\(start\)\#<=\_.\{-}\(stop\)\#=
The match will stop at any occurrence of “stop”, even if it is escaped:
test start test \stop test stop test
^^^^^^^
To fix this behaviour, we may replace \_. (which matches any character, including newlines) by the disjunction of \_[^\\] (which matches any character but a backslash) and \\\_. (which matches a backslash followed by any character). This means that any non‐escaped backslash will be interpreted as the beginning of an escaping sequence. Backslashes themselves can be escaped, so that \\stop is an escaped backslash followed by a true closing delimiter.
Here is the Braille expression:
\(start\)\#<=\(\_[^\\]\|\\\_.\)\{-}\(stop\)\#=
and some tests:
test start test \stop test stop test
^^^^^^^^^^^^^^^^^
test start test \\stop test stop test
^^^^^^^^
test start test \\\stop test stop test
^^^^^^^^^^^^^^^^^^^
I am trying to figure out a way to determine if my matched comma(,) does not lie inside a regex. Basically, i do not want to match my character if it lies in a regex.
The regex i have come up with is ,(?<!.+\/)(?!.+\/) but its not quite working.
Any ideas?
I want to skip /some,regex/ but match any other commas.
Edit:
Live example: http://rubular.com/r/WjrwSnmzyP
Here is the regex that will work for you:
,(?!\s)(?=(?:(?:[^/]*\/){2})*[^/]*$)
Live Demo: http://rubular.com/r/37buDdg1tW
Explanation: It means match comma followed by EVEN number of forward slash /. Hence comma (,) between 2 slash (/) characters will NOT be matched and outside ones will be matched (since those are followed by even number of / characters).
A curious thing about regular expressions is that if you want to use them to ignore "something" that is within "something else", you need to match that "something else", prefer matches of it, and then either silently discard or reproduce those matches.
For example, in order to remove all commas from a string unless they are in a regular expression literal—
In Perl:
my $s = "/foo,bar/,baz";
$s =~ s{(/(?:[^/\\]|\\.)+/)|,}{\1}g;
In ECMAScript:
var s = "/foo,bar/,baz";
s = s.replace(/(\/([^\/\\]|\\.)+\/)|,/g, "$1");
or
s = s.replace(new RegExp("(/([^/\\\\]|\\\\.)+/)|,", "g"), "$1");
Note that I am capturing the match for the regular expression literal in the string value, and reproducing it (\1 or $1) if it matched. (If the other part of the alternation – the standalone comma – matched, the empty string is captured, so this simple approach suffices here.)
For further reading I recommend “Mastering Regular Expressions” by Jeffrey E. F. Friedl. Two rather enlightening example chapters, each from a different edition, are available for free online.