Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# Stripping / converting one or more characters

Is there a fast way (without having to explicitly looping through each character in a string) and either stripping or keeping it. In Visual FoxPro, there is a function CHRTRAN() that does it great. Its on a 1:1 character replacement, but if no character in the alternate position, its stripped from the final string. Ex

CHRTRAN( "This will be a test", "it", "X" )

will return

"ThXs wXll be a es"

Notice the original "i" is converted to "X", and lower case "t" is stripped out.

I looked at the replace for similar intent, but did not see an option to replace with nothing.

I'm looking to make some generic routines to validate multiple origins of data that have different types of input restrictions. Some of the data may be coming from external sources, so its not just textbox entry validation I need to test for.

Thanks

like image 587
DRapp Avatar asked Nov 28 '22 12:11

DRapp


2 Answers

All you need is a couple of calls to String.Replace().

string s = "This will be a test";
s = s.Replace("i", "X");
s = s.Replace("t", "");

Note that Replace() returns a new string. It does not alter the string itself.

like image 63
Jon B Avatar answered Dec 06 '22 21:12

Jon B


Does this what you want?

"This will be a test".Replace("i", "X").Replace("t", String.Empty)

Here is a simple implementation of the CHRTRAN function - it does not work if the string contains \0 and is quite messy. You could write a nicer one using loops, but I just wanted to try it using LINQ.

public static String ChrTran(String input, String source, String destination)
{
    return source.Aggregate(
        input,
        (current, symbol) => current.Replace(
            symbol,
            destination.ElementAtOrDefault(source.IndexOf(symbol))),
        preResult => preResult.Replace("\0", String.Empty));
}

And the you can use it.

// Returns "ThXs wXll be a es"
String output = ChrTran("This will be a test", "it", "X");

Just to have a clean solution - the same without LINQ and working for the \0 cases, too, and it is almost in place because of using a StringBuilder but won't modify the input, of course.

public static String ChrTran(String input, String source, String destination)
{
    StringBuilder result = new StringBuilder(input);

    Int32 minLength = Math.Min(source.Length, destination.Length);

    for (Int32 i = 0; i < minLength; i++)
    {
        result.Replace(source[i], destination[i]);
    }

    for (Int32 i = minLength; i < searchPattern.Length; i++)
    {
        result.Replace(source[i].ToString(), String.Empty);
    }

    return result.ToString();
}

Null reference handling is missing.

Inspired by tvanfosson's solution, I gave LINQ a second shot.

public static String ChrTran(String input, String source, String destination)
{
    return new String(input.
        Where(symbol =>
            !source.Contains(symbol) ||
            source.IndexOf(symbol) < destination.Length).
        Select(symbol =>
            source.Contains(symbol)
                ? destination[source.IndexOf(symbol)]
                : symbol).
        ToArray());
}
like image 27
Daniel Brückner Avatar answered Dec 06 '22 20:12

Daniel Brückner