Regular Expression question Visual Studio - c#

I'm wanting to replace all references to a resource file in my C# code.
An example is a page that contains several references such as:
Resources.Global.Firstname
Resources.Global.Surname
I'd like the regular expression to find all of these (they could end either with a ; or a )).
Total beginner with regular expressions, so any advice here would be gratefully received.

You can just use the Find and Replace window in Visual Studio.
Press Ctrl-H to open the window.
Put Resources\.Global\.{[^,) ;]+} in the "Find what:" text box.
Put GetStringValue("\1") in the "Replace with:" text box.
Make sure the "Look in:" dropdown is set to the scope you want to search
Expand the Find options subpanel.
Check the box next to "Use:" and make sure that "Regular expressions" is selected.
What this is doing:
The first regular expression will find anything that starts with Resources.Global. and capture whatever is after it until it finds a space, a comma, a close paren, or a semi-colon.
The second one replaces the entire text that was found with GetStringValue("") and puts the captured text inside the quotes in the parentheses.

Why not just do CTRL+H (quick find and replace) and search on the actual terms rather than the regex pattern? What are you trying to rename from and to?
UPDATE
The pattern to match would be something like: Resources.Global.([^};]+)
Replace pattern would be GetStringValue("\1")

As Blazes said, in the scenario you mentioned, Refactoring is the actual answer. If you just want to see them, right click on the definition and select Find all references. If you want to change it, just make the changes and then press ctrl+shift+F11, a context menu appears which gives you the chance to rename all references.

Regular expression:
(Resources\.Global\.[A-Z][a-zA-Z]*[;\)])
will find only the last two lines out of the following tested lines:
Resources.Global.Firstname
Resources.Global.Surname
Resources.Global.Firstname;
Resources.Global.Surname)
used code to verify:
Regex regex = new Regex(#"(Resources\.Global\.[A-Z][a-zA-Z]*[;\)])");
MatchCollection mc = regex.Matches("Resources.Global.Firstname\n" +
"Resources.Global.Surname" +
"Resources.Global.Firstname;" +
"Resources.Global.Surname)");
foreach (Match match in mc)
{
Console.WriteLine(match.Groups[1].ToString());
}
This software might help you:
Rad Software Regular Expression Designer

Related

C# Matching a recursive structure in a string

I'm currently working on a program that loads up a text file, searches through it to find a specific structure, and then replaces a certain part of that structure with different text.
The structure I need to find and extract is "N"(N) where N is any character. For example. Lets say I had a text file like this:
Everyone knows the saying "Do not do more than you can do" (Jim Doe).
Well, I'm here to tell you that this saying is awesome. Here is
another, "The sky is blue and the sun is bright" (Sally Wantsmore).
I would want to be able to match the text "Do not do more than you can do" (Jim Doe) along with "The sky is blue and the sun is bright" (Sally Wantsmore).
I don't think there is really a way to do this with a regular expression from the best of my knowledge. I've been trying for the last few days. I can't get it to work, it's a recursive pattern by nature. My question is, how would I go about writing C# code to parse through and find these patterns. I would like to do something where I can find the position within the string and the length, that way I can then extract it from the string.
EDIT
I need to be able to capture all characters in the quote. This means that there could also be another set of quotes within the quote and even another set of parenthesis. This means that the structure could also contain a match within itself.
I'm now trying to use this expression because I need to be able to capture all characters within a quote: \"(.+)\" \(([\w ]+)\)
The listed answers below both work. However, I've discovered a limitation. There is a possible recursive structure to this. The problem I am currently having is when there is a "N"(N) inside of a "N"(N)". For example:
"Random quote" (random person) Here is a fun saying, "The sky is blue and
the sun is bright, some even say "really bright" (others)" (Sally
Wantsmore).
This presents many problems. There is only one match because it takes the very first ", and then finds the last " just after (others) and finds the set of parens for (Sally Wantsmore) and only finds that match. However, I desire for it to find all the matches, especially the beginning one and last one separably, and even the inner quote. Is this possible with Regular expressions? If not, how do I go about solving this with Recursive c# code.
The following regex should find the two things you're looking for:
\"([\w ]+)\" \(([\w ]+)\)
In C# you can use Regex.Match to retrieve the two items in brackets.
An example on how you could have it in C#:
var quotes = Regex.Matches(#"Everyone knows the saying ""Do not do more than you can do"" (Jim Doe). Well, I'm here to tell you that this saying is awesome. Here is another, ""The sky is blue and the sun is bright"" (Sally Wantsmore).",
"(?<Quotes>\"(?<Text>[\\w ]+)\\\" \\((?<Author>[\\w ]+)\\))", RegexOptions.Singleline);
foreach (Match quote in quotes)
{
var text = quote.Groups["Text"].Value;
var author = quote.Groups["Author"].Value;
Console.WriteLine($"Text: {text}, Author: {author}");
}

Possible to remove/replace code in entire solution

I have multiple lines of code in my solution that I'd like to remove.
They are, in this particular scenario:
System.Diagnostics.Trace.WriteLine([STRING]);
I could've done a 'Replace All' on System.Diagnostics.Trace.WriteLine but, obviously, I want to remove the entire thing (including the string parameter passed into the method) - I want the whole line of code to be deleted wherever a call to this method is made.
Is there a way in which I can do this (any way to provide a wildcard included in the replace criteria maybe?). Also, could I do this with comments/todo's too?
I appreciate this may seem bad practice to have to get to this point but would, for now, appreciate answers that are only on topic as opposed to answers that try and propose ways of preventing this in the future (which I've already acknowledged).
You can use Regular Expression in Visual Studio Find and Replace dialog, use:
Find: ^[ \t]*(System.Diagnostics.Trace.WriteLine\(.*\)\;).*\n
Replace:
That's will delete the entire line.
You'll need to use the Regular Expression option in the Replace dialog, and something like this should do:
System.Diagnostics.Trace.WriteLine\("\w*"\);
Cheers
EDIT: Obviously, if you are passing variables to WriteLine, just remove the quotes:
System.Diagnostics.Trace.WriteLine\(\w*\);
If you mean to remove all instances of System.Diagnostics.Trace.WriteLine then you could do the following:
Go to Replace in Files dialog box
Enter System.Diagnostics.Trace.WriteLine.* in the find what box
Leave the Replace with box empty
Choose Entire Solution for Look in
Expand Find Options and tick Use and ensure Regular Expressions is shown.

Regex Help (again)

I don't really know what to entitle this, but I need some help with regular expressions. Firstly, I want to clarify that I'm not trying to match HTML or XML, although it may look like it, it's not. The things below are part of a file format I use for a program I made to specify which details should be exported in that program. There is no hierarchy involved, just that each new line contains a 'tag':
<n>
This is matched with my program to find an enumeration, which tells my program to export the name value, anyway, I also have tags like this:
<adr:home>
This specifies the home address. I use the following regex:
<((?'TAG'.*):(?'SUBTAG'.*)?)?(\s+((\w+)=('|"")?(?'VALUE'.*[^'])('|"")?)?)?>
The problem is that the regex will split the adr:home tag fine, but fail to find the n tag because it lacks a colon, but when I add a ? or a *, it then doesn't split the adr:home and similar tags. Can anyone help? I'm sure it's only simple, it's just this is my first time at creating a regular expression. I'm working in C#, by the way.
Will this help
<((?'TAG'.*?)(?::(?'SUBTAG'.*))?)?(\s+((\w+)=('|"")?(?'VALUE'.*[^'])('|"")?)?)?>
I've wrapped the : capture into a non capturing group round subtag and made the tag capture non greedy
Not entirely sure what your aim is but try this:
(?><)(?'TAG'[^:\s>]*)(:(?'SUBTAG'[^\s>:]*))?(\s\w+=['"](?'VALUE'[^'"]*)['"])?(?>>)
I find this site extremely useful for testing C# regex expressions.
What if you put the colon as part of the second tag?
<((?'TAG'.*)(?':SUBTAG'.*)?)?(\s+((\w+)=('|"")?(?'VALUE'.*[^'])('|"")?)?)?>

C# Regex Replace ignore specific string

Since this is my first question here on stackoverflow I hope my question is correctly asked.
Basicly I have a normal .txt file which contains any text like:
car accident
people died
cat without owner
<!-- Text added at 6/29/2011 9:20:38 AM -->
Some addintional Text
other Text added
add Text
I have a write/append function which allows the user to append some text and set a little timestamp.
So my problem is: With another function, you can search and replace text in the textfile, but as you can guess if someone wants to replace the word "Text" it will be replaced in the xml-stylish comment(timestamp) as well.
My result until now is
content = Regex.Replace(content,"[^<+.*"+input+".*>+]*", replace);
//content = content of the .txt file, input = search term, replace = string to replace
But this fails miserably, as some regex pro's will see without executing it.
Now I hope that some regex pro could help me out here and provide me a search pattern which replaces the normal text but ignores the timestamp.
I'm not realy aware of the logic from regex until now, nevertheless I understand the single expressions so this would be a hook for me to understand Regex more properly.
Thanks in advice.
If I understand your question correctly, you want to replace every instance of "Text" except for the one(s) inside the comment.
The easist way is to use a negative lookbehind (fantastic description here) as below:
content = Regex.Replace(content, #"(?<!<!--.*?)" + input, replace);
What you're doing is attempting to replace a repetition of any length of a character that is NOT <+.*> or a character contained in input with the value in replace.
If you're going to be working a lot with Regex, I would HIGHLY recommend giving the website above a good read. It's hands down the best intro to Regex that I've found, the time spent now will save you lots of headaches later!
Edit
Updated to add flexibility thanks to #stema

XML repair in C#

The file format my application uses is Xml based. I just got a customer who has a botched xml file. The thing contains nearly 90,000 lines and for some reason there are about 20 "=" symbols randomly interspersed.
I get an XmlException for most of them with a line number and char position which allows me to find offending chars and remove them manually. I've just started writing a small app that automates this process, but I was wondering if there are better ways to repair damaged xml files.
Example of botched line:
<item name="InstanceGuid" typ=e_name="gh_guid" type_code="9">ee330f9f-a1e2-451a-8c6d-723f066a6bd4</item>
↑ (this is supposed to be [type_name])
You could search for any equal sign that isn't followed by a double quote. A regular expression (regex) would be pretty simple to write up.
Or you could just open the file in an advanced text editor and search by that same regex expression to find and replace/remove. Some text editors allow you to find/replace with regex, so you could search for any equal sign not followed by double quote and just remove it.
Of course, I'd keep a copy of the original since if you had equal signs in the inner XML then it might mess it up, etc.
Use a regular expression to clean the xml first.
something like:
s/([^\s"]+)=([^\s"]+="[^"]*")/\1\2/
Obviously this would need to be ported to your Regex engine of choice :)
In TextPad if you search using the regular expression =[^"] you will find any = signs not followed by a "
This should find the locations in the document where the rogue = signs have appeared. To replace them, first open the document in TextPad. Then press F8.
In the dialog enter the following:
Find what: =\([^"]\)
Replace with: \1
Check the "Regular expressions" box, select "All documents" and click "Replace All"
This should match all = that aren't followed by a " and replace the = with the symbol that did follow it.
typename="test" typ=ename="test"
will become
typename="test" typename="test"

Categories

Resources