Replace a text by incrementing each occurence - c#

I have a text say:
Hello
abc
Hello
def
Hello
I want to convert it to
Hello1
abc
Hello2
abc
Hello3
i.e I need to append a number after each occurrence of "Hello" text.
Currently I have written this code:
var xx = File.ReadAllText("D:\\test.txt");
var regex = new Regex("Hello", RegexOptions.IgnoreCase);
var matches = regex.Matches(xx);
int i = 1;
foreach (var match in matches.Cast<Match>())
{
string yy = match.Value;
xx = Replace(xx, match.Index, match.Length, match.Value + (i++));
}
and the Replace method above used is:
public static string Replace(string s, int index, int length, string replacement)
{
var builder = new StringBuilder();
builder.Append(s.Substring(0, index));
builder.Append(replacement);
builder.Append(s.Substring(index + length));
return builder.ToString();
}
Currently the above code is not working and is replacing the text in between.
Can you help me fixing that?

Assuming Hello is just a placeholder for a more complex pattern, here is a simple fix: use a match evaluator inside Regex.Replace where you may use variables:
var s = "Hello\nabc\nHello\ndef\nHello";
var i = 0;
var result = Regex.Replace(
s, "Hello", m => string.Format("{0}{1}",m.Value,++i), RegexOptions.IgnoreCase);
Console.WriteLine(result);
See the C# demo

Related

Find quoted strings and replace content between double quotes

I have a string, e.g.
"24.09.2019","545","878","5"
that should be processed to
"{1}","{2}","{3}","{4}"
Now I am trying to use regular expression:
string replacementString="{NG}";
Regex regex = new Regex("\\\"[0-9\.]+\\\"");
MatchCollection matches = regex.Matches(originalString);
List<string> replacements = new List<string>();
for (int x = 0; x < matches.Count; x++)
{
string replacement = String.Copy(replacementString);
replacement = replacement.Replace("NG", (x + 1).ToString());
replacements.Add(replacement);
Match match = matches[x];
}
replacements.Reverse();
int cnt = 0;
foreach (var match in matches.Cast<Match>().Reverse())
{
originalStringTmp = originalStringTmp.Replace(
match.Index,
match.Length,
replacements[cnt]);
cnt++;
}
And
public static string Replace(this string s, int index, int length, string replacement)
{
var builder = new StringBuilder();
builder.Append(s.Substring(0, index));
builder.Append(replacement);
builder.Append(s.Substring(index + length));
return builder.ToString();
}
But in this case the result is
{1},{2},{3},{4}
What regular expression should I use instead of
\"[0-9\.]+\"
to achieve the result
"{1}","{2}","{3}","{4}"
with C# regular expression?
Let's try Regex.Replace in order to replace all the quotations (I've assumed that quotation is escaped by itself: "abc""def" -> abc"def) within the string:
string source = "\"24.09.2019\",\"545\",\"878\",\"5\"";
int index = 0;
string result = Regex.Replace(source, "\"([^\"]|\"\")*\"", m => $"\"{{{++index}}}\"");
Demo:
Func<string, string> convert = (source => {
int index = 0;
return Regex.Replace(source, "\"([^\"]|\"\")*\"", m => $"\"{{{++index}}}\"");
});
String[] tests = new string[] {
"abc",
"\"abc\", \"def\"\"fg\"",
"\"\"",
"\"24.09.2019\",\"545\",\"878\",\"5\"",
"name is \"my name\"; value is \"78\"\"\"\"\"",
"empty: \"\" and not empty: \"\"\"\""
};
string demo = string.Join(Environment.NewLine, tests
.Select(test => $"{test,-50} -> {convert(test)}"));
Console.Write(demo);
Outcome:
abc -> abc
"abc", "def""fg" -> "{1}", "{2}"
"" -> "{1}"
"24.09.2019","545","878","5" -> "{1}","{2}","{3}","{4}"
name is "my name"; value is "78""""" -> name is "{1}"; value is "{2}"
empty: "" and not empty: """" -> empty: "{1}" and not empty: "{2}"
Edit: You can easily elaborate the replacement, e.g. if you want to replace integer numbers only
Func<string, string> convert = (source => {
int index = 0;
// we have match "m" with index "index"
// out task is to provide a string which will be put instead of match
return Regex.Replace(
source,
"\"([^\"]|\"\")*\"",
m => int.TryParse(m.Value.Trim('"'), out int _drop)
? $"\"{{{++index}}}\"") // if match is a valid integer, replace it
: m.Value); // if not, keep intact
});
In general case
Func<string, string> convert = (source => {
int index = 0;
// we have match "m" with index "index"
// out task is to provide a string which will be put instead of match
return Regex.Replace(
source,
"\"([^\"]|\"\")*\"",
m => {
// now we have a match "m", with its value "m.Value"
// its index "index"
// and we have to return a string which will be put instead of match
// if you want unquoted value, i.e. abc"def instead of "abc""def"
// string unquoted = Regex.Replace(
// m.Value, "\"+", match => new string('"', match.Value.Length / 2));
return //TODO: put the relevant code here
}
});
string originalString = "\"24.09.2019\",\"545\",\"878\",\"5\"";
var regex = new Regex("\"[0-9\\.]+\"");
var matches = regex.Matches(originalString);
string result = string.Join(',', Enumerable.Range(1, matches.Count).Select(n => $"\"{{{n}}}\""));
Input:
"24.09.2019","545","878","5"
Result:
"{1}","{2}","{3}","{4}"

Getting a numbers from a string with chars glued

I need to recover each number in a glued string
For example, from these strings:
string test = "number1+3"
string test1 = "number 1+4"
I want to recover (1 and 3) and (1 and 4)
How can I do this?
CODE
string test= "number1+3";
List<int> res;
string[] digits= Regex.Split(test, #"\D+");
foreach (string value in digits)
{
int number;
if (int.TryParse(value, out number))
{
res.Add(number)
}
}
This regex should work
string pattern = #"\d+";
string test = "number1+3";
foreach (Match match in Regex.Matches(test, pattern))
Console.WriteLine("Found '{0}' at position {1}",
match.Value, match.Index);
Note that if you intend to use it multiple times, it's better, for performance reasons, to create a Regex instance than using this static method.
var res = new List<int>();
var regex = new Regex(#"\d+");
void addMatches(string text) {
foreach (Match match in regex.Matches(text))
{
int number = int.Parse(match.Value);
res.Add(number);
}
}
string test = "number1+3";
addMatches(test);
string test1 = "number 1+4";
addMatches(test1);
MSDN link.
Fiddle 1
Fiddle 2
This calls for a regular expression:
(\d+)\+(\d+)
Test it
Match m = Regex.Match(input, #"(\d+)\+(\d+)");
string first = m.Groups[1].Captures[0].Value;
string second = m.Groups[2].Captures[0].Value;
An alternative to regular expressions:
string test = "number 1+4";
int[] numbers = test.Replace("number", string.Empty, StringComparison.InvariantCultureIgnoreCase)
.Trim()
.Split("+", StringSplitOptions.RemoveEmptyEntries)
.Select(x => Convert.ToInt32(x))
.ToArray();

Want to get more than 1 value by using regex c#

> String St = "New Specification Result : Measures 0.0039mm ( 4 Microns )New Specification Result : Measures 0.0047mm ( 5 Microns )";
The string that i want to get is 0.0039mm and 0.0047mm but the code i use keep giving me 0.0047mm only.
var src = st;
var pattern = #"([0-9].[0-9]{4}mm)";
var expr = new Regex(pattern, RegexOptions.IgnoreCase);
foreach (Match match in expr.Matches(src))
{
string key = match.Groups[1].Value;
string key2 = match.Groups[2].Value;
label1.Text = key + key2;
}
Your code is fine, and the millimeter number you are trying to match is being captured correctly, but in the first capture group, and not in the second. There is a slight problem with your pattern, and it should be this:
([0-9]\.[0-9]{4}mm)
You intend for the dot to be a literal decimal point, so it should be escaped with a backslash. Here is the full code:
var pattern = #"([0-9].[0-9]{4}mm)";
var expr = new Regex(pattern, RegexOptions.IgnoreCase);
foreach (Match match in expr.Matches(src))
{
string key = match.Groups[1].Value;
string key2 = match.Groups[2].Value; // this doesn't match to anything here
Console.WriteLine(key);
}
Demo
You want the following. Your loop is is overwriting your copy of the first result (and you don't have a 2nd capture group. You have a 2nd match)
var st = "New Specification Result : Measures 0.0039mm(4 Microns)New Specification Result: Measures 0.0047mm(5 Microns";
var pattern = #"([0-9]\.[0-9]{4}mm)";
var expr = new Regex(pattern, RegexOptions.IgnoreCase);
string key = "";
foreach (Match match in expr.Matches(st))
{
key += match.Groups[1].Value;
}
you want to iterate through each match and the join them together for display
var mm = new Regex(#"([0-9]\.[0-9]{4}mm)").Matches(src).Select(m => m.Groups[1]).ToList();
var list = string.Join(" ", mm);
label1.Text = list;
currently you are only getting the last match as you keep overwriting the text in your label

Retrieve String Containing Specific substring C#

I am having an output in string format like following :
"ABCDED 0000A1.txt PQRSNT 12345"
I want to retreieve substring(s) having .txt in above string. e.g. For above it should return 0000A1.txt.
Thanks
You can either split the string at whitespace boundaries like it's already been suggested or repeatedly match the same regex like this:
var input = "ABCDED 0000A1.txt PQRSNT 12345 THE.txt FOO";
var match = Regex.Match (input, #"\b([\w\d]+\.txt)\b");
while (match.Success) {
Console.WriteLine ("TEST: {0}", match.Value);
match = match.NextMatch ();
}
Split will work if it the spaces are the seperator. if you use oter seperators you can add as needed
string input = "ABCDED 0000A1.txt PQRSNT 12345";
string filename = input.Split(' ').FirstOrDefault(f => System.IO.Path.HasExtension(f));
filname = "0000A1.txt" and this will work for any extension
You may use c#, regex and pattern, match :)
Here is the code, plug it in try. Please comment.
string test = "afdkljfljalf dkfjd.txt lkjdfjdl";
string ffile = Regex.Match(test, #"\([a-z0-9])+.txt").Groups[1].Value;
Console.WriteLine(ffile);
Reference: regexp
I did something like this:
string subString = "";
char period = '.';
char[] chArString;
int iSubStrIndex = 0;
if (myString != null)
{
chArString = new char[myString.Length];
chArString = myString.ToCharArray();
for (int i = 0; i < myString.Length; i ++)
{
if (chArString[i] == period)
iSubStrIndex = i;
}
substring = myString.Substring(iSubStrIndex);
}
Hope that helps.
First split your string in array using
char[] whitespace = new char[] { ' ', '\t' };
string[] ssizes = myStr.Split(whitespace);
Then find .txt in array...
// Find first element starting with .txt.
//
string value1 = Array.Find(array1,
element => element.Contains(".txt", StringComparison.Ordinal));
Now your value1 will have the "0000A1.txt"
Happy coding.

Get String (Text) before next upper letter

I have the following:
string test = "CustomerNumber";
or
string test2 = "CustomerNumberHello";
the result should be:
string result = "Customer";
The first word from the string is the result, the first word goes until the first uppercase letter, here 'N'
I already tried some things like this:
var result = string.Concat(s.Select(c => char.IsUpper(c) ? " " + c.ToString() : c.ToString()))
.TrimStart();
But without success, hope someone could offer me a small and clean solution (without RegEx).
The following should work:
var result = new string(
test.TakeWhile((c, index) => index == 0 || char.IsLower(c)).ToArray());
You could just go through the string to see which values (ASCII) are below 97 and remove the end. Not the prettiest or LINQiest way, but it works...
string test2 = "CustomerNumberHello";
for (int i = 1; i < test2.Length; i++)
{
if (test2[i] < 97)
{
test2 = test2.Remove(i, test2.Length - i);
break;
}
}
Console.WriteLine(test2); // Prints Customer
Try this
private static string GetFirstWord(string source)
{
return source.Substring(0, source.IndexOfAny("ABCDEFGHIJKLMNOPQRSTUVWXYZ".ToArray(), 1));
}
Z][a-z]+ regex it will split the string to string that start with big letters her is an example
regex = "[A-Z][a-z]+";
MatchCollection mc = Regex.Matches(richTextBox1.Text, regex);
foreach (Match match in mc)
if (!match.ToString().Equals(""))
Console.writln(match.ToString() + "\n");
I have tested, this works:
string cust = "CustomerNumberHello";
string[] str = System.Text.RegularExpressions.Regex.Split(cust, #"[a-z]+");
string str2 = cust.Remove(cust.IndexOf(str[1], 1));

Categories