Ignore regex separator between "display name" - c#

I need to split the string with the separator ">," but this separator is allowed between the "" that correspond to the display name e.g:
""display>, name>," <email#tegg.com>, "<display,> >" <display_a#email.com>";
I need it to be separated like:
[["display>, name>," <email#tegg.com>,] ["<display,> >" <display_a#email.com>"]]
I'm using at this moment this:
aux = Regex.Split(addresses, #"(?<=\>,)");
But this doesnt work when the display name has ">,"
E.g str:
str = "\"Some name>,\" <example#email.com>, \"<display,> >\" <display_a#email.com>'";

You can use
var matches = Regex.Matches(str, #"""([^""]*)""\s*<([^<>]*)>")
.Cast<Match>()
.Select(x => new[] { x.Groups[1].Value, x.Groups[2].Value })
.ToArray();
See the C# demo:
var p = #"""([^""]*)""\s*<([^<>]*)>";
var str = "\"Some name>,\" <example#email.com>, \"<display,> >\" <display_a#email.com>'";
var matches = Regex.Matches(str, p).Cast<Match>().Select(x => new[] { x.Groups[1].Value, x.Groups[2].Value }).ToArray();
foreach (var pair in matches)
Console.WriteLine("{0} : {1}", pair[0],pair[1]);
Output:
Some name>, : example#email.com
<display,> > : display_a#email.com
See also the regex demo. Details:
" - a " char
([^"]*) - Group 1: any zero or more chars other than "
" - a " char
\s* - zero or more whitespaces
< - a < char
([^<>]*) - Group 2: any zero or more chars other than < and >
> - a > char

Related

replacing words

I want to replace the first and last words of the sentence which I typed in the console.
if I type the following sentence in console:
London is the Capital of UK.
I need such result
UK is the capital of London.
You could use following method and String.Split + String.Join:
public static void SwapFirstAndLast<T>(IList<T>? items)
{
if (items == null || items.Count < 2) return;
T first = items[0];
items[0] = items.Last();
items[^1] = first;
}
string sentence = " London is the Capital of UK";
string[] wordDelimiters = { " " };
string[] words = sentence.Trim().Split(wordDelimiters, StringSplitOptions.RemoveEmptyEntries);
SwapFirstAndLast(words);
sentence = string.Join(" ", words);
In more generic case when we should take punctuation into account, e.g.
London, being a vast area, is the capital of UK =>
=> UK, being a vast area, is the capital of London
we can use regular expressions to match words. Assuming that word is a
sequence of letters and apostrophes we can use
[\p{L}']+
pattern and do the following:
using System.Text.RegularExpressions;
...
string text = "London, being a vast area, is the capital of UK";
// All words matched
var words = Regex.Matches(text, #"[\p{L}']+");
// Replace matches: first into last,
// last into first, all the others keep intact
int index = -1;
var result = Regex.Replace(
text,
#"[\p{L}']+",
m => {
index += 1;
if (index == 0)
return words[^1].Value;
if (index == words.Count - 1)
return words[0].Value;
return m.Value;
});
``

How do I check if a string contains "(1)" and if it does, increase the number by 1?

If a any given string, at the end contains "(" followed by a number, + ")", i want to increase that value by one. If not Ill just add a "(1)".
Ive tried with something like string.Contains(), but since the value within () can be diffrent i don't know how to always search like this and get the number.
To find a parentheses enclosed number at the end of a string, and increase b 1, try this:
Regex.Replace(yourString, #"(?<=\()\d+(?=\)$)", match => (int.Parse(match.Value) + 1).ToString());
Explanation:
(?<=\() is a positive look-behind, which matches an open bracket, but does not include it in the match result.
\d+ matches one or more digits.
(?=\)$) is a positive look-ahead, which matches a closing bracket at the end of the string.
To add a number if none is present, test the match first:
string yourString = "A string with no number at the end";
string pattern = #"(?<=\()\d+(?=\)$)";
if (Regex.IsMatch(yourString, pattern))
{
yourString = Regex.Replace(yourString, pattern, match => (int.Parse(match.Value) + 1).ToString());
}
else
{
yourString += " (1)";
}
You can try regular expressions: Match and Replace the desired fragment, e.g.
using System.Text.RegularExpressions;
...
string[] tests = new string[] {
"abc",
"def (123)",
"pqr (123) def",
"abs (789) (123)",
};
Func<string, string> solution = (line) =>
Regex.Replace(line,
#"\((?<value>[0-9]+)\)$",
m => $"({int.Parse(m.Groups["value"].Value) + 1})");
string demo = string.Join(Environment.NewLine, tests
.Select(test => $"{test,-20} => {solution(test)}"));
Console.Write(demo);
Outcome:
abc => abc # no numbers
def (123) => def (124) # 123 turned into 124
pqr (123) def => pqr (123) def # 123 is not at the end of string
abs (789) (123) => abs (789) (124) # 123 turned into 124, 789 spared
If we put
Func<string, string> solution = (line) => {
Match m = Regex.Match(line, #"\((?<value>[0-9]+)\)$");
return m.Success
? line.Substring(0, m.Index) + $"({int.Parse(m.Groups["value"].Value) + 1})"
: line + " (1)";
};
Edit: If we want to put (1) if we haven't any match we can try Match and replace matched text:
abc => abc (1)
def (123) => def (124)
pqr (123) def => pqr (123) def (1)
abs (789) (123) => abs (789) (124)
string s = "sampleText";
string pattern = "[(]([0-9]*?)[)]$";
for (int i = 0; i < 5; i++)
{
var m = Regex.Match(s, pattern);
if (m.Success)
{
int value = int.Parse(m.Groups[1].Value);
s = Regex.Replace(s, pattern, $"({++value})");
}
else
{
s += "(1)";
}
Console.WriteLine(s);
}
If I understand correctly you have strings such as :
string s1 = "foo(12)"
string s2 = "bar(21)"
string s3 = "foobar"
And you want to obtain the following:
IncrementStringId(s1) == "foo(13)"
IncrementStringId(s2) == "bar(22)"
IncrementStringId(s3) == "foobar(1)"
you could accomplish this by using the following method
public string IncrementStringId(string input)
{
// The RexEx pattern is looking at the very end of the string for any number encased in paranthesis
string pattern = #"\(\d*\)$";
Regex regex = new Regex(pattern);
Match match = regex.Match(input);
if (match.Success)
if (int.TryParse(match.Value.Replace(#"(", "").Replace(#")", ""), out int index))
//if pattern in found parse the number detected and increment it by 1
return Regex.Replace(input, pattern, "(" + ++index + ")");
// In case the pattern is not detected add a (1) to the end of the string
return input + "(1)";
}
Please make sure you are using System.Text.RegularExpressions namespace that includes Regex class.

How to return the amount of duplicate letters in a string

I am trying to get a user's input so that I can return how many duplicate characters they have.
This is how I got the input
Console.WriteLine("Input a word to reveal duplicate letters");
string input = Console.ReadLine();
For example, the code should return something like:
List of duplicate characters in String 'Programming'
g : 2
r : 2
m : 2
How do I find duplicate letters and count them in a string?
Yes you can obtain this by using System.Linq GroupBy(), you going to group your string by character value and after filter the generated groups that have more than 1 values like so :
var word = "Hello World!";
var multipleChars = word.GroupBy(c => c).Where(group => group.Count() > 1);
foreach (var charGroup in multipleChars)
{
Console.WriteLine(charGroup .Key + " : " + charGroup .Count());
}
this will include case sensitivity as well as excluding non alphanumeric char
var sample = Console.ReadLine();
var letterCounter = sample.Where(char.IsLetterOrDigit)
.GroupBy(char.ToLower)
.Select(counter => new { Letter = counter.Key, Counter = counter.Count() })
.Where(c=>c.Counter>1);
foreach (var counter in letterCounter){
Console.WriteLine(String.Format("{0} = {1}", counter.Letter,counter.Counter));
}

How to use Regex to split a string AND include whitespace

I can't seem to find (or write) a simple way of splitting the following sentence into words and assigning a word to the whitespace between the letters.
(VS 2010, C#, .net4.0).
String text = "This is a test.";
Desired result:
[0] = This
[1] = " "
[2] = is
[3] = " "
[4] = a
[5] = " "
[6] = test.
The closest I have come is:
string[] words = Regex.Split(text, #"\s");
but ofcourse, this drops the whitespace.
Suggestions are appreciated. Thanks
Edit: There may be one or more spaces between the words. I would like all spaces between the words to be returned as a "word" itself (with all spaces being placed in that "word"). e.g., if 5 spaces between a word would be.
String spaceword = " "; <--This is not showing correctly, there should be a string of 5 spaces.
Change your pattern to (\s+):
String text = "This is a test.";
string[] words = Regex.Split(text, #"(\s+)");
for(int i =0; i < words.Length;i++)
{
Console.WriteLine(i.ToString() + "," + words[i].Length.ToString() + " = " + words[i]);
}
Here's the output:
0,4 = This
1,8 =
2,2 = is
3,1 =
4,1 = a
5,3 =
6,5 = test.
You can use LINQ to add spaces manually between them:
var parts = text.Split(new[]{ ' ' }, StringSplitOptions.RemoveEmptyEntries);
var result = parts.SelectMany((x,idx) => idx != parts.Length - 1
? new[] { x, " " }
: new[] { x }).ToList();
You can try this regex, \w+|\s+ which uses or operator |
var arr = Regex.Matches(text, #"\S+|\s+").Cast<Match>()
.Select(i => i.Value)
.ToArray();
It just matches both words and spaces and some LINQ stuff is being used so arr is just a String Array

Find NOT matching characters in a string with regex?

If Im able to check a string if there are invalid characters:
Regex r = new Regex("[^A-Z]$");
string myString = "SOMEString";
if (r.IsMatch(myString))
{
Console.WriteLine("invalid string!");
}
it is fine. But what I would like to print out every invalid character in this string? Like in the example SOMEString => invalid chars are t,r,i,n,g. Any ideas?
Use LINQ. Following will give you an array of 5 elements, not matching to the regex.
char[] myCharacterArray = myString.Where(c => r.IsMatch(c.ToString())).ToArray();
foreach (char c in myCharacterArray)
{
Console.WriteLine(c);
}
Output will be:
t
r
i
n
g
EDIT:
It looks like, you want to treat all lower case characters as invalid string. You may try:
char[] myCharacterArray2 = myString
.Where(c => ((int)c) >= 97 && ((int)c) <= 122)
.ToArray();
In your example the regex would succeed on one character since it's looking for the last character if it isn't uppercase, and your string has such a character.
The regex should be changed to Regex r = new Regex("[^A-Z]");.
(updated following #Chris's comments)
However, for your purpose the regex is actually what you want - just use Matches.
e.g.:
foreach (Match item in r.Matches(myString))
{
Console.WriteLine(item.ToString() + " is invalid");
}
Or, if you want one line:
foreach (Match item in r.Matches(myString))
{
str += item.ToString() + ", ";
}
Console.WriteLine(str + " are invalid");
Try with this:
char[] list = new char[5];
Regex r = new Regex("[^A-Z]*$");
string myString = "SOMEString";
foreach (Match match in r.Matches(myString))
{
list = match.Value.ToCharArray();
break;
}
string str = "invalid chars are ";
foreach (char ch in list)
{
str += ch + ", ";
}
Console.Write(str);
OUTPUT: invalid chars are t, r, i, n, g

Categories