Visual Studio hangs searching for regex ^.*$ - regex

(To clarify, I'm talking about Ctrl-Shift-F search. Current Document.)
I want to search for lines that don't contain a certain character, like '(', so I figure I need to include ^ and $ indicators to get the entire line. But this just crashes the GUI. Is there a way forward?
Lines without ( should be handled by this:
^[^\(]*$
But this hangs, as does the simpler "^.*$".
Maybe there's another way to find these lines?
EDIT: the proposed "duplicate" question is about C# RegEx class, completely utterly different from Visual Studio 2010 interactive regular expressions.

If you want to match lines, use ^[^\r\n(]*$, where \r and \n are excluded from [^(] – Wiktor Stribiżew Jun 27 at 19:36
This comment is indeed the answer. Apparently old Visual Studio searches could span multiple lines, and ^.*$ thus means start at the beginning of the line, go forward any number of characters up to the end of the document, then stop at the end of a line. These characters can include any number of newlines.
VS apparently didn't efficiently implement this query and hangs interminably.
W.S.'s proposal explicitly excludes newlines from the search parameters, thereby forcing only a single line.
Visual Studio 2012 changes to more conventional regular expression search which limits results to within single lines, so ^.*$ will just fetch all the lines of a document one by one.

Related

RegEx for underlining text

How can I match one line of text with a regex and follow it up with a line of dashes exactly as many as characters in the initial match to achieve text-only underlining. I intend to use this with the search and replace function (likely in the scope of a macro) inside an editor. Probably, but not necessarily, Visual Studio Code.
This is a heading
should turn into
This is a heading
-----------------
I believe I have read an example for that years ago but can't find it; neither do I seem to be able to formulate a search query to get anything useful out of Google (including variations of the question's title). If you are I'd be interested in that, too.
The best I can come up with is this:
^(.)(?=(.*\n?))|.
Substitution
$1$2-
syntax
note
^(.)
match the first character of a line, capture it in group 1
(?=(.*\n?))
then look ahead for the rest of this line and capture it in group 2, including a line break if there's any
|.
or a normal character
But the text must has a line break after it, or the underline only stays on the same line.
Not sure if it is any useful but here are the test cases.

Why does a regular expression with a positive lookbehind in Visual Studio cause every second match to be substituted?

Given the following regular expression containing a positive lookbehind (simplified from the one I'm actually trying to use):
(?<=\s|\n)(".*?")
and the following substitution expression:
_T($1)
Visual Studio 2013 will find every matching string but when replacing, will replace the string corresponding to the subsequent match, so will replace every second string.
Furthermore, Replace All does not work and says it cannot find any matching text (even though a Find All will find the relevant strings).
Is this a bug in Visual Studio or am I doing something wrong?
Demo:
TLDR; Visual Studio (VS) search/replace using VS Regexe's have to work with Visual Studio operations and what appears to be a valid regex will not work because of all the moving parts.
Explanation Because there are actually multiple things working against that lookbehind pattern in visual studio. Each of them is working in separately to achieve what you are seeing; but they are individual actions and not a cabal of one thought failure. Let me list them via 1/2/3:
#1: When using any type of lookbehind/ahead in regular expression patterns, one must note that it doesn't capture what it specifies in the lookbehind. The capture happens on what comes after it. So your "Find Next" item doesn't capture the space or linefeed behind it. (It is what you want and this is logical) but see below how the space before it is not captured and each set is highlighted and how that interferes with the whole process.
Stand alone this works and is what is intended, as a search/highlight, but then #2 comes into play.
#2: Visual Studio editor is not a true regex replace operation. Because it is doing a two step operation to do a replace; these steps are not integrated like a code regex replace. Let that sink in.
Step one is a find, step 2 is a replace. Replace all is multiple two step (Find/Replace) operations til end of file from current location.
On this single replace skip issue, on the first press, because Replace Next has to first find the next item, it doesn't replace it; by design It just moves the highlight to the next "XXXXXX" string.
(Press 2) The user thinks Studio is going to replace what is highlighted, but that doesn't happen in this case, because the match pattern states that the current match position must have \s|\n within in it; curses, the lookbehind!
Because it doesn't have \s|\n of the lookbehind in the current selection it must move the text point which is the next location after the current highlight, and if found does a replace there.
To be clear, because the replace operation is sitting on a quote and not a \s|\n (as directed by the pattern), it must move the current pointer to the next \s|\n which it finds it and replaces the text. Note the two clicks in blue that happen to do the
#3: What is interesting is that if one doesn't do the match replacement, $1, but just some text, replace all works, uggg confusing.
Because the replace match $1 is not viable in any individual search/replace step, the replace all the operation subsequently locks up.
Summary
What you want to do is logical, but because the regex replace with a lookbehind is jiggering with the editor pointer and the two step find/replace with regex operation, a conjunction of individual scenarios is causing the whole operation to fail.
One has to design a visual studio regex pattern to work with the #1/#2/#3 editor idiosyncrasies as pointed out above. Keep in mind that VS regex is not true .NET regex parser...just a close one-off.
Is it a bug? Maybe. But IMHO a fix would require a whole redesign of search/replace feature to be more regex centric than plain text search centric (with regex patterns) like it is now.

visual Studio 2010 regular expressions for 'Find In Files'

I have look at the many stackoverflow posts concerning VS regular expressions and read the Microsoft page concerning regular expressions but still cannot determine where I am going wrong.
Microsoft VS regex
I want to find all lines which include the word, attribute, but which are not comment lines (do not contain the // symbol).
I have tried using the regular expression
~(^ *//).*attribute.*
meaning:
~(^ *//) --> exclude lines which begin with '//' preceded by zero or more spaces
.* --> match any character zero or more times
attributes --> match the word attributes
.* --> match any character that comes after the word attribute
I have tried several other regular expressions with about the same amount of failure. I am wondering if anyone can spot something obvious that I am not doing.
I also gave the below a try:
~( *//).*attribute.* (thinking maybe the carat was being taken as a literal instead of special)
~(//).*attribute.* (thinking maybe the * was being taken as a literal instead of special)
~(//)attribute (imminent failure but will try anything)
\s*~(//).*attributes.*
I saw quite a few posts suggesting to use the find command in batch. This can be done, but I would prefer to have the ability to double click on the findings so that the file will be opened and already scrolled to the correct location.
How about this one.
^(?=.*attribute.*\n)(?!.*//).*

Find newline in Visual Studio 2013

I have a C++ source file containing many functions.
I want to find the beginning of every function quickly.
How can I form an expression for )newline{newline?
The newline symbol can be either one of the following:
\n
\r
\n\r
\r\n
Presumably, the same symbol is used all across the file, so instead of a single expression for all options combined, I need a single expression for each option.
I assume that a regular-expression can be used, but I'm not sure how.
Thanks
Barak, before we look at individual options, for all options, this will do it:
\)[\r\n]+{[\r\n]+
The [\r\n] is a character class that allows either of \r or \n. It is quantified with a + which means we are looking for one or more of these characters.
You said you want individual options, so this can be turned to:
\)\r\n{\r\n
\)\r{\r
\)\n{\n
\)\n\r{\n\r (this sequence of newlines is quite surprising)
If you simply want to use the regex search in VS to find the beginning of each function then this should work for you:
\)\r?\n\s*{\r?\n
Although that assumes the { is always on the next line with no white space before the line break.
This would be less strict where white space is concerned, but still expect the { to be on the next line and to be followed by a line break:
\)\s*\r?\n\s*{\s*\r?\n
And this would basically just look for the 2 brackets even if they're on the same line:
\)\s*\r?\n?\s*{
And if you expect there could be several line breaks between the 2 brackets:
\)\s*(\r?\n\s*)*{
Last example should find anything that could resemble the beginning of a method. But not sure how strict you want your search to be.

Multi-line regular expressions in Visual Studio

Is there any way to get Visual Studio to perform a regex replace across multiple lines (let the match cross line boundaries)? I know there are many editors I can use for this, but it seems strange that this feature has been left out of Visual Studio. Am I missing something?
Regular expressions have changed in Visual Studio 2013. https://msdn.microsoft.com/en-us/library/2k3te2cs(v=vs.120).aspx
To match an expression over two lines the code would now be:
StartOfExpression.*\r?\n.*EndOfExpression
Use (.*\n)*? to skip zero or more lines between your expressions.
start(.*\n)*?end
finds
start
two
three
end
? is the non-greedy operator, used to skip as few lines as possible.
If end is not the first word in the line, add .* to match the extra characters. I.e.: start(.*\n)*?.*end finds
start
two
three
four end end
If you only want to replace until the first end, add another non-greedy operator: start(.*\n)*?.*?end.
Historic: In Visual Studio 2017 (and early versions of 2019) you can also use the single line option in the Find and Replace dialog Ctrl-Shift-F like this:
(?s)start.*end
For more see the version history of this answer.
This works today in Visual Studio 2012:
fooPatternToStart.*(.*\n)+?.*barPatternToEnd
See how the (.*\n)+? part does the match across multiple lines, non-greedy.
fooPatternToStart is some regex pattern on your start line, while barPatternToEnd is your pattern to find on another line below, possibly many lines below...
Example found here.
Simple and effective :)
Note: before VS2012, the pattern that worked was: fooPatternToStart.(.\n)+#.*barPatternToEnd
Note: this answer is using the regex syntax used in Visual Studio up to and including VS 2012. In VS 2013 and later, the regex syntax has changed.
You can include \n in the expression. As an example, here is a regex that I use to "clean" auto-generated SQL scripts from anything that is not a stored procedure (it will match text blocks that start with a line containing "Object: " followed by something that is not "StoredProcedure", then matching the following lines up to a line consists of the word "GO"):
/\*+ Object\::b:b~(StoredProcedure)(.*\n)#GO\n
you may need to use \r\n at the end of your expression.
Non-greedy multi-line any character capture, Visual Studio 2013+:
.*?\r?\n.*?
Greedy version in Giles Roberts's answer.
For everyone coming here while searching for VS Code, I use this to match anything from script to anywhere with 2 newlines (newlines excluded):
script(.|\n)+?(?=\n\n)
replace script and \n\n to match everything between them.