Replacing text using regular expression with variable text? - c#

Lets say I have some text with lots of instances of word "Find", which I want to replace it with text like "Replace1","Replace2","Replace3", etc. The number is the occurrence count of "Find" in the text.
How to do it in the most effective way in C#, I already know the loop way.

A MatchEvaluator can do this:
string input = "FindbcFinddefFind", pattern = "Find";
int i = 1;
string replaced = Regex.Replace(input, pattern, match => "REPLACE" + i++);
Note that the match variable also has access to the Match etc. With C# 2.0 you'll need to use an anonymous method rather than a lambda (but same effect) - to show both this and the Match:
string input = "FindbcFinddefFind", pattern = "Find";
int i = 1;
string replaced = Regex.Replace(input, pattern, delegate(Match match)
{
string s = match.Value.ToUpper() + i;
i++;
return s;
});

You could use the overload that takes a MatchEvaluator and provide the custom replacement string inside the delegate implementation, which would allow you to do all the replacements in one pass.
For example:
var str = "aabbccddeeffcccgghhcccciijjcccckkcc";
var regex = new Regex("cc");
var pos = 0;
var result = regex.Replace(str, m => { pos++; return "Replace" + pos; });

Related

How to remove number from string after a specific character C#

I have a string that i need to remove the last number from the string.
For example
abc/wed/ash/123 or
abc/tues/1 or
abc/thurs/clou/nice/12
The string does not have a set amount of / in it, however I would like to separate the number after the last / from the string.
Therefore I would like to get
abc/wed/ash and 123
Everything I found needed a set amount of / in it for it to work.
If you need both halves you could try this:
var s = "abc/thurs/clou/nice/12";
var index = s.LastIndexOf('/');
var number = Int32.Parse(s.Substring(index + 1)); //12
var leftHalf = s.Substring(0, index); //abc/thurs/clou/nice
Get the last index of "/" on your input string, then use that result in Substring:
var input = "abc/wed/ash/123";
var lastIndex = input.LastIndexOf("/");
var part1 = input.Substring(0, lastIndex); // "abc/wed/ash"
var part2 = input.Substring(lastIndex + 1); // "123"
You can use regular expressions:
const string Input = "abc/def/123";
var regex = new Regex(#"(.+)/(\d+)$");
foreach (var group in regex.Match(Input).Groups)
Console.WriteLine(group.ToString());
Console.ReadKey();
UPDATE
OK, maybe I should do some explaining. By specifying a pattern, you can express quite cleanly what are the parts of your input that are of interest to you. In this case, for example, the pattern #(.+)/(\d+) tells the engine that you expect the input to contain any number of any characters, then a dash, then a number of digits. $ means that should be the end of the input.
When processing text input, consider regular expressions. :)
You can accomplish this in a variety of approaches, the cleanest approach is the answer by Francies. Which would be:
// Performant:
var input = "/Product/Electrical/Wire/4421";
var index = input.LastIndexOf('/');
var id = int.Parse(input.Substring(index + 1));
var url = input.Substring(0, index);
You could also do the following, which is a nice alternative syntax wise:
// Easy to read syntax.
var input = "/Product/Electrical/Wire/4421";
var id = input.Skip(input.LastIndexOf('/') + 1);
var url = input.Take(input.LastIndexOf('/'));
If you only need the number, you could do:
var input = "/Product/Electrical/Wire/4421";
var id = input.Split('/').Last();
Regex is your friend
Regex regex = new Regex(#"(.*?)(\d+)$");
Match match = regex.Match("abc/tues/1");
Console.WriteLine(match.Groups[1].Value); -->abc/tues/
Console.WriteLine(match.Groups[2].Value); -->1

Substring from path string

In strings like this (I get strings from Directory.GetFiles())
string temp = "\\folder_name\\file_name.filetype.[somename#somedomain].wallet"
What is the best way to substring: file_name.filetype
I could do something like this:
const string source = ".[somename#somedomain].wallet";
temp.Substring(0, temp.IndexOf(source, StringComparison.Ordinal));
... but problem is that "mail" in string ".[xxxx#xxxx].wallet" is changing, in my words my string source should be something like this:
const string source = ".[*].wallet"; //so all strings that are in .[all_strings].wallet
Is there an easy way to do something like this (with asterisk "*"), or I will have to substring piece by piece and concatenate this new string?
You can construct a regex that requires a backslash before the substring of interest, and a text in square brackets followed by .wallet at the end.
Here is how you can do with in C# regex APIs:
string temp = #"\folder_name\file_name.filetype.[somename#somedomain].wallet";
var m = Regex.Match(temp, #"(?<=\\)[^.]*\.[^.]*(?=\.\[[^\]]*\].wallet)");
if (m.Success) {
Console.WriteLine(m.Value);
} else {
Console.WriteLine("<no match>");
}
Demo.
(?<=...) and (?=...) constructs are zero-length look-ahead and look-behind. They are not included in the m.Value.
You could search for the 2nd index of . and take everything before that point.
string temp = "\\folder_name\\file_name.filetype.[somename#somedomain].wallet";
var filename = Path.GetFileName(temp);
var lastIndex = filename.IndexOf('.', filename.IndexOf('.') + 1);
var fileYouAreLookingFor = filename.Substring(0, lastIndex);
Working fiddle
You could also use an regex to achieve this. The first group of the following one should be what you are looking for.
string temp = "\\folder_name\\file_name.filetype.[somename#somedomain].wallet";
var filenameRegex = new Regex("^.*\\\\(.*)\\.\\[.*\\]\\.wallet$");
var match = filenameRegex.Match(temp);
var result = match.Groups[1];

In C#, what is the recommended way to parse out a word inside certain characters?

In C#, I have a string coming in that I am reading into a variable that looks like this
var fullString = "Some random text (importantword)"
what is the easiest way to parse out the "importantword"? RegEx? doing just .IndexOf() for the "(" and ")" characters?
IndexOf is definitely the easiest.
https://msdn.microsoft.com/en-us/library/aa287734%28v=vs.71%29.aspx
Followed by a Substring.
var startIndex = fullString.IndexOf("(") + 1;
var endIndex = fullString.IndexOf(")");
var targetWord = fullString.Substring(startIndex, endIndex - startIndex);
EDIT: As pointed out in the comments below, I forgot startIndex was for the opening parenthesis instead of the actual word.
Regular expressions have two drawbacks: they may be slow compared to IndexOf() and they are usually not easy to read and understand. In your case, finding the text in parenthesis is easy and doesn't need regular expressions.
If your string always ends with ), then you can search for just the ( and remove the last character:
var start = fullString.IndexOf('(') + 1;
var end = fullString.Length - 1;
return fullString.Substring(start, end - start);
Otherwise, do both searches. In this last case, remember to use the IndexOf(char, int) overload to avoid searching for the entire string:
var start = fullString.IndexOf('(') + 1;
var end = fullString.IndexOf(')', start); // Notice the `start`
return fullString.Substring(start, end - start);
You could use capturing groups or lookarounds to get all the characters present between () brackets.
String input = #"Some random text (importantword)";
Regex rgx = new Regex(#"(?<=\()[^()]*(?=\))");
foreach (Match m in rgx.Matches(input))
Console.WriteLine(m.Groups[0].Value);
OR
String input = #"Some random text (importantword)";
Regex rgx = new Regex(#"\(([^()]*)\)");
foreach (Match m in rgx.Matches(input))
Console.WriteLine(m.Groups[1].Value);

Substring or split word in clamp

I need an solution for my problem. I have a clause like:
Hello guys I am cool (test)
An now I need an effective method to split just only the part in the parentheses and the result should be:
test
My try is to split the String in words like. But I don't think it is the best way.
string[] words = s.Split(' ');
I do not think that split is the solution to your problem
Regex is very good for extracting data.
using System.Text.RegularExpression;
...
string result = Regex.Match(s, #"\((.*?)\)").Groups[1].Value;
This should do the trick.
Assuming:
var input = "Hello guys I am cool (test)";
..Non-Regex version:
var nonRegex = input.Substring(input.IndexOf('(') + 1, input.LastIndexOf(')') - (input.IndexOf('(') + 1));
..Regex version:
var regex = Regex.Match(input, #"\((\w+)\)").Groups[1].Value;
You can use regex for this:
string parenthesized = Regex.Match(s, #"(?<=\()[^)]+(?=\))").Value;
Here's an explanation of the various parts of the regex pattern:
(?<=\(): Lookbehind for the ( (excluded from the match)
[^)]+: Sequence of characters consisting of anything except )
(?=\)): Lookahead for the ) (excluded from the match)
The most efficient way is using string methods but you don't need Split but Substring and IndexOf. Note that this currently just finds a single word in parentheses:
string text = "Hello guys I am cool (test)";
string result = "--no parentheses--";
int index = text.IndexOf('(');
if(index++ >= 0) // ++ used to look behind ( which is a single character
{
int endIndex = text.IndexOf(')', index);
if(endIndex >= 0)
{
result = text.Substring(index, endIndex - index);
}
}
string s = "Hello guys I am cool (test)";
var result = s.Substring(s.IndexOf("test"), 4);

C#: Parse substring from a string by detecting whitespace

If I have various strings that have text followed by whitespace followed by text, how can I parse the substring beginning with the first character in the second block of text?
For example:
If I have the string:
"stringA stringB"
How can I extract the substring
"stringB"
The strings are of various lengths but will all be of the format .
I'm sure this can be easily done with regex but I'm having trouble finding the proper syntax for c#.
No RegEx needed, just split it.
var test = "stringA stringB";
var second = test.Split()[1];
and if you are in the wonderful LINQ-land
var second = "string1 string2".Split().ElementAtOrDefault(1);
and with RegEx (for completeness)
var str2 = Regex.Match("str1 str2", #"\w (.*$)").Groups[1].Value;
use string.Split()
var test = "stringA stringB";
var elements = test.Split(new[]
{
' '
});
var desiredItem = elements.ElementAtOrDefault(1);
if you want to capture all whitespaces (msdn tells us more):
var test = "stringA stringB";
//var elements = test.Split(); // pseudo overload
var elements = test.Split(null); // correct overload
var desiredItem = elements.ElementAtOrDefault(1);
edit:
why pseudo-overload?
.Split() gets compiled to .Split(new char[0])
not documented in MSDN
If all strings are separated by a whitespace you don't need a regex here. You could just use the Split() method:
string[] result = { };
string myStrings = "stringA stringB stringC";
result = myStrings.Split(' ');
You don't need event the Split(). I think a simple IndexOf/Substring will do the job.
var input = "A B";
var result = string.Empty;
var index = input.IndexOf(' ');
if (index >= 0)
{
result = input.Substring(index + 1);
}

Categories