Regex combine more than 1 function - c#

How can I call 2 functions in my code for one string?
public static string ecleaner(string str)
{
return Regex.Replace(str, "[éèê]+", "e", RegexOptions.Compiled);
}
public static string acleaner(string str)
{
return Regex.Replace(str, "[áàâ]+", "a", RegexOptions.Compiled);
}
Now I want to check the word "Téèááést" ,after this it should look like Teaest .

You could use a MatchEvaluator delegate, like this:
public static string cleaner(string str)
{
return Regex.Replace(str, "(?<a>[áàâ]+)|(?<e>[éèê]+)", onMatch, RegexOptions.Compiled);
}
private static string onMatch(Match m)
{
if (m.Groups["a"].Success)
return "a";
if (m.Groups["e"].Success)
return "e";
return "";
}
Or alternatively:
public static string cleaner(string str)
{
var groups = new[] { "a", "e" };
return Regex.Replace(str, "(?<a>[áàâ]+)|(?<e>[éèê]+)", m => groups.First(g => m.Groups[g].Success), RegexOptions.Compiled);
}

Did you try this?
string str = "Téèááést";
str = ecleaner(str);
str = acleaner(str);

public static class StringExtensions
{
public static string ecleaner(this string str)
{
return Regex.Replace(str, "[éèê]+", "e", RegexOptions.Compiled);
}
public static string acleaner(this string str)
{
return Regex.Replace(str, "[áàâ]+", "a", RegexOptions.Compiled);
}
}
//...
var result = "Téèááést".ecleaner().acleaner();
You could also combine an extension method class with #p.s.w.g's answer, to make things even neater.

Related

Regex or loop in loop

I have a function: bool ContainsOneOf(string str1, string validchars) which get 2 strings and checks if one of the letters in one string is in the other string.
Here's the code:
public static bool ContainsOneOf(string str1, string validchars)
{
foreach (char ch in str1)
{
foreach (char ch2 in validchars)
{
if (ch == ch2)
{
return true;
}
}
}
return false;
}
Other way to write it by using regex:
public static bool ContainsOneOf(string str1, string validchars)
{
return Regex.IsMatch(str1, #"[" + validchars + "]");
}
Which way should I use? (efficient)
Regex.IsMatch has too much overhead, I would use Enumerable.Any:
static bool ContainsOneOf(string str1, string validchars)
{
return str1.Any(c => validChars.Contains(c));
}
I suggest using linq:
public static bool ContainsOneOf(string str1, string validchars)
{
return str1.Any(ch => validchars.Any(ch2 => ch == ch2));
}
Or
public static bool ContainsOneOf(string str1, string validchars)
{
return (from ch in str1 from ch2 in validchars where ch == ch2 select ch).Any();
}
Just a variation to the other answers: I would switch str1 and validChars in the check, and also change the type of validChars to IEnumerable as to make it more reusable. Also, making it an extension method makes sense.
static bool ContainsOneOf(this string str1, IEnumerable<char> validchars)
{
return validchars.Any(c => str1.Contains(c));
}
An alternative to the other answers posted so far:
public static bool ContainsOneOf(string str1, string validchars)
{
return str1.IndexOfAny(validchars.ToCharArray()) != -1;
}
More on String.IndexOfAny:
https://msdn.microsoft.com/en-us/library/system.string.indexofany(v=vs.110).aspx

C# : Search the "v" which may or may not occur in the end of the string

So, I have a C# string input which can be either "ABCD12345678" or "ABCD1234" or "ABCD1233456v1" or "ABCD1233456v2" or "AVVV1233456v334" or "ABVV1233456V4".
I need to manipulate and remove the last may or may not be occurring "v"/"V" and get the result like :
"ABCD1233456"
"ABVV1233456"
"AVVV1233456"
Please help. If I use substring straightforward it works for only those where "v" occurs but throws exception for those where it doesn't occur.
It's a little confusing when you say at the end because the v isn't really at the end...
Anyway, what about Regex?
public static class VRemover
{
public static string Process(string input)
{
var regex = new Regex(#"(?'util'[a-z]+\d+)(v\d*)?", RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture);
return regex.IsMatch(input)
? regex.Match(input).Groups["util"].Value
: input;
}
}
You can validate with this test (NUnit):
[TestFixture]
public class VRemoverTests
{
[Test]
public void Test()
{
var inputs = new[]
{
"ABCD12345678",
"ABCD1234",
"ABCD1233456v1",
"ABCD1233456v2",
"AVVV1233456v334",
"ABVV1233456V4"
};
var expecteds = new[]
{
"ABCD12345678",
"ABCD1234",
"ABCD1233456",
"ABCD1233456",
"AVVV1233456",
"ABVV1233456"
};
for (var i = 0; i < inputs.Length; i++)
{
var actual = VRemover.Process(inputs[i]);
Assert.AreEqual(expecteds[i], actual);
}
}
}
private static string RemoveString (string input)
{
var indexOf = input.LastIndexOf("v", StringComparison.OrdinalIgnoreCase);
if (indexOf < 0)
return input;
return input.Substring(0, indexOf);
}
private string ReplaceLastV(string input)
{
if (input.IndexOf("v", StringComparison.OrdinalIgnoreCase) > 0)
{
int lastIndexV = input.LastIndexOf("v", StringComparison.OrdinalIgnoreCase);
return input.Substring(0, lastIndexV);
}
return input;
}

Cannot implicitly convert string[][] to string[] in C#

I'm getting this error in new keyword.
//Code:
public static string[] SplitStrings(string inboundString, char splitChar)
{
if(inboundString.Contains(splitChar))
{
return new[] { inboundString.Split(splitChar) };
}
}
You don't need to create a new array the return from split works just fine.
public static string[] SplitStrings(string inboundString, char splitChar)
{
if(inboundString.Contains(splitChar))
{
return inboundString.Split(splitChar);
}
else
{
return new string[] {};
}
}
Try it like this
public static string[] SplitStrings(string inboundString, char splitChar)
{
return inboundString.Split(splitChar);
}
String.Split itself returns a string[] so you don`t need to initialize a new one.

Linq statement to get a string that is not substring of a longer string

I have a long string S that may contain pattern p1, p2, p3, ....;
All patterns are put in a MatchCollection object
I would like to do something like
string ret=p_n if !(S.Contains(p_n))
I write a for loop to do this
foreach(string p in PatternList)
{
s=(!S.contain(p.valus))?p.value:"";
}
I would like to know a LINQ statement to make my cocde more elgant.
var patterns = new List<string> { "one", "two", "three" };
var misses = patterns.Where(s => !longString.Contains(s));
class Program
{
static void Main(string[] args)
{
string S = "12345asdfasdf12w3e412354w12341523142341235123";
string patternString = "one1234554321asdf";
MatchCollection p_ns = Regex.Matches(patternString, "one|12345|54321|asdf");
var nonMatches = (from p_n in p_ns.Cast<Match>()
where !S.Contains(p_n.Value)
select p_n.Value);
foreach (string nonMatch in nonMatches)
{
Console.WriteLine(nonMatch);
}
Console.ReadKey();
}
}
Or to use Justin's method from his answer you could also use the below variation.
class Program
{
static void Main(string[] args)
{
string S = "12345asdfasdf12w3e412354w12341523142341235123";
string patternString = "one1234554321asdf";
MatchCollection p_ns = Regex.Matches(patternString, "one|12345|54321|asdf");
var nonMatches = p_ns.Cast<Match>().Where(s => !S.Contains(s.Value));
foreach (Match nonMatch in nonMatches)
{
Console.WriteLine(nonMatch.Value);
}
Console.ReadKey();
}
}
static void Main(string[] args)
{
string S = "p1, p2, p3, p4, p5, p6";
List<string> PatternList = new List<string>();
PatternList.Add("p2");
PatternList.Add("p5");
PatternList.Add("p9");
foreach (string s in PatternList.Where(x => !S.Contains(x)))
{
Console.WriteLine(s);
}
Console.ReadKey();
}

Linq or string filter

I need a filter on the string which takes another string as a parameter, scans first string and removes all appearances of it.
You can use string.Replace which has an overload specifically for this.
var newString = oldString.Replace("foo", string.Empty);
This takes your oldString, finds all occurrences of "foo" and removes them.
This would work
var s = "string";
s = s.Replace("st", string.Empty);
// s == "ring";
Is that not correct?
Use extension methods:
public static class StringExtensions
{
public static string RemoveOccurences(this string s, string occurence)
{
return s.Replace(occurence, "");
}
}
usage:
string s = "Remove all appearances of this and that and those";
s.RemoveOccurences("th");

Categories