Problem with regular expression replacement in Visual Studio 2003 - regex

I'm in the process of converting some LaTeX documentation to restructured text and having some trouble with a regular expression in Visual Studio 2003. I'm trying to convert \emph{text} to *text* using the following find/replace strings:
\\emph\{([^\}]*)\}
*\0*
However, using this pair I get \emph{text} converted to *\emph{text}* which was not what I expected. When I use *\1* instead of *\0* I get ** as the replacement result.
What am I missing or what don't I understand about the grouping rules?
Thanks.

I think that in the VS regex replacement syntax, \0 is the whole matched string, while \1 is the content of the first captured variable (\2 being the second and so on). Therefore:
\0
However, using this pair I get
\emph{text} converted to *\emph{text}*
which was not what I expected.
Thus confirming, \0 is the whole matched string.
When I use *\1* instead of *\0* I get ** as the replacement result.
Probably you are not matching anything in the capture class.
To add more detail, the syntax for defined a capture class (called a tagged expression in the docs) uses the braces {}, not parentheses () as you are using here. Probably this will work as the "find" expression:
\\emph\{{[^\}]*}\}

Related

Regex in Visual Studio Comunity

I'm trying to replace a code using Regex in visual studio community, but I'm not getting it.
ZeroMemory(&ab,15);
ZeroMemory(&abc,30);
ZeroMemory(&tickt,sizeof(tickt));
To replace
memset(&ab,0,15);
memset(&abc,0,30);
memset(&tickt,0,sizeof(tickt));
I need to replace zeromemory with memset and the first one with ,0,
thank you all in advance
Clearly you are asking about the "Find and Replace" feature in Visual Studio.
As a starting point, something like this should do what you want:
From: ZeroMemory\s*\((.*),
To: memset($1, 0,
Because parentheses are used in regular expressions for matching groups, you need to escape them (\() if you want to match an actual parenthesis.
Then we use (.*) to create a group that captures whatever your first parameter is. Note that this is very naive. If you have a non-trivial expression for that argument (e.g. a function call where a comma appears anywhere) this will likely fail.
So that matches the stuff you want, and then for the replacement you can use $1 to substitute the first matching group (in which we captured your first argument).
The only extra detail I added was a \s* between the function identifier and the parenthesis. This matches optional whitespace characters, so it will still match even if you have stuff like:
ZeroMemory (foo, bar);
I recommend you read the documentation to familiarize yourself with regular expressions in Visual Studio.

VSCode Regex Find/Replace In Files: can't get a numbered capturing group followed by numbers to work out

I have a need to replace this:
fixed variable 123
with this:
fixed variable 234
In VSCode this matches fine:
fixed(.*)123
I can't find any way to make it put the capture in the output if a number follows:
fixed$1234
fixed${1}234
But the find replace window just looks like this:
I read that VSCode uses rust flavoured rexes.. Here indicates ${1}234 should work, but VSCode just puts it in the output..
Tried named capture in a style according to here
fixed(?P<n>.*)123 //"invalid regular expression" error
VSCode doesn't seem to understand ${1}:
ps; I appreciate I could hack it in the contrived example with
FIND: fixed (.*) 123
REPL: fixed $1 234
And this does work in vscode:
but not all my data consistently has the same character before the number
After a lot of investigation by myself and #Wiktor we discovered a workaround for this apparent bug in vscode's search (aka find across files) and replace functionality in the specific case where the replace would have a single capture group followed by digits, like
$1234 where the intent is to replace with capture group 1 $1 followed by 234 or any digits. But $1234 is the actual undesired replaced output.
[This works fine in the find/replace widget for the current file but not in the find/search across files.]
There are (at least) two workarounds. Using two consecutive groups, like $1$2234 works properly as does $1$`234 (or precede with the $backtick).
So you could create a sham capture group as in (.*?)()(\d{3}) where capture group 2 has nothing in it just to get 2 consecutive capture groups in the replace or
use your intial search regex (.*?)(\d{3}) and then use $` just before or after your "real" capture group $1.
OP has filed an issue https://github.com/microsoft/vscode/issues/102221
Oddly, I just discovered that replacing with a single digit like $11 works fine but as soon as you add two or more it fails, so $112 fails.
I'd like to share some more insights and my reasoning when I searched for a workaround.
Main workaround idea is using two consecutive backreferences in the replacement.
I tried all backreference syntax described at Replacement Strings Reference: Matched Text and Backreferences. It appeared that none of \g<1>, \g{1}, ${1}, $<1>, $+{1}, etc. work. However, there are some other backreferences, like $' (inserts the portion of the string that follows the matched substring) or $` (inserts the portion of the string that precedes the matched substring). However, these two backreferences do not work in VS Code file search and replace feature, they do not insert any text when used in the replacement pattern.
So, we may use $` or $' as empty placeholders in the replacement pattern.
Find What:      fix(.*?)123
Replace With:
fix$'$1234
fix$`$1234
Or, as in my preliminary test, already provided in Mark's answer, a "technical" capturing group matching an empty string, (), can be introduced into the pattern so that a backreference to that group can be used as a "guard" before the subsequent "meaningful" backreference:
Find What: fixed()(.*)123 (see () in the pattern that can be referred to using $1)
Replace With: fixed$1$2234
Here, $1 is a "guard" placeholder allowing correct parsing of $2 backreference.
Side note about named capturing groups
Named capturing groups are supported, but you should use .NET/PCRE/Java named capturing group syntax, (?<name>...). Unfortunately, the none of the known named backreferences work replacement pattern. I tried $+{name} Boost/Perl syntax, $<name>, ${name}, none work.
Conclusion
So, there are several issues here that need to be addressed:
We need an unambiguous numbered backerence syntax (\g<1>, ${1}, or $<1>)
We need to make sure $' or $` work as expected or are parsed as literal text (same as $_ (used to include the entire input string in the replacement string) or $+ (used to insert the text matched by the highest-numbered capturing group that actually participated in the match) backreferences that are not recognized by Visual Studio Code file search and replace feature), current behavior when they do not insert any text is rather undefined
We need to introduce named backreference syntax (like \g<name> or ${name}).

Find Regex mismatch part in a string using vb.net

I had a regex expression
^\d{9}_[a-zA-Z]{1}_(0[1-9]|1[0-2]).(0[1-9]|[1-2][0-9]|3[0-1]).[0-9]{4}_\d*_[0-9a-zA-Z]*_[0-9a-zA-Z]*
and string that match regex expression
000066874_A_12.31.2014_001_2Q_ICAN14
if user by mistake enters the string other than above format like
000066874_12.31.14_001_2Q_ICAN14
I need to find out in which part of my regex got failed. I tried using Regex.Matches and Regex.Match but using this I couldn't find in which part my string got miss matched with my Regex expression. I am using vb.net
This is very complicated to do with regex. I managed to make this regex, but you still have to check the capture groups after that.
^(?:(?:(\d{9})|.*?)_)?(?:(?:([a-zA-Z]{1})|.*?)_)?(?:(?:((?:0[1-9]|1[0-2]).(?:0[1-9]|[1-2][0-9]|3[0-1]).[0-9]{4})|.*?)_)?(?:(?:(\d*)|.*?)_)?(?:(?:([0-9a-zA-Z]*)|.*?)_)?(?:([0-9a-zA-Z]*)|.*?)$ will work if you, as seen in demo: https://regex101.com/r/aJ1wG1/2
Each part before an underline is a capture group, if a capture group is not there, there's an error in it. As you can see in the example, $3 is not present in 1st example, hence, a mistake in date is there. In second example, the $2 is not present, hence $2 onward are not there. 3rd example is correct and all 6 caputre groups are there.
When regexes get this massive, it's a sign that probably a different method should be used to solve the problem, but this might work for you with some additional code for group result checks.

Find and replace string within a specific string with regex in visual studio

I'd like to replace automatically all the strings in my solution which are like this one
NotifyPropertyChanged("VariableParameter")
with this
NotifyPropertyChanged(Function() VariableParameter)
by "Quick Replace" in "Find and Replace" using a regular expression in Visual Studio 2010.
I have not the slightest idea how to do this when I have to keep each different variable parameter.
Try the following pattern and replacement.
Pattern: NotifyPropertyChanged\("{[^"]+}"\)
This matches your text, while escaping the parentheses. The {[^"]+} portion tags the contents (via the curly braces) and the [^"]+ bit matches any character that isn't a double-quote, one or more times.
Replacement: NotifyPropertyChanged(Function() \1)
This replaces the matched text and is fairly straightforward to understand. The \1 portion refers to the first (and only, in this example) tagged text from the pattern, which is the content between double-quotes.

Need help with a file path validation regular expression

I am using a RegularExpressionValidator in visual studio and I am struggling to create the correct regular expression for my needs. Here is what I want:
The input can contain any character except <>:"/|?*
Also, the input can not contain two backslashes in a row
So, your\mom would be ok but your\\mom would fail as would your*mom
The closest I have come at this point is something like
^(?=.*[^<>:"/|?*])(?:[^\\]+|\\(?:$|[^\\])).{0,100}$
but it doesn't work.
^(?!.*\\\\)[^<>:"/|?*]*$
should do it.
(?!.*\\\\) asserts that there are no two backslashes in a row in the string.
[^<>:"/|?*]* matches any number of characters except the ones inside the character class.
That is, unless you're talking about the regex features of Visual Studio (the IDE environment itself) which has a wildly nonstandard regex flavor.