简体   繁体   中英

C#, check string if 'a letter' is followed by 'a letter'

Let say, * has to be followed by &. For example,

string asd = "Mother*&Mother*&Son";
// which is "Mother+ "*&" + "Mother" + "*&" + "Son"
// This is correct string.

Bad example,

string asd = "Mother*Mother*&Son";
string asf = "Mother**&Mother*&Son";
string asg = "Mother*&*Mother*&Son";

How can I check if the string is correct or not in C#?

EDIT
based on the usage of Regex that you guys introduced, I have a side question. I am actually using comma(,) instead of asterisk(*) and quotation mark(") instead of ampersand(&). In C#, (Let me use one of the guy's example)

Regex.IsMatch("Mother,\",Mother,\"Son", @"\,(?!")") 
//won't work.. any idea? 

I also tried

Regex.IsMatch("Mother,\",Mother,\"Son", @"\,(?!\")") 
//not work, neither

查找故障通过寻找任何星号( * )后面没有符号( & ):

Regex.IsMatch("Mother*&*Mother*&Son", @"\*(?!&)")

You can use regex. But it will be easier to find when string is not correct and then just negate the result.

I would look for any * which is not followed by & . The regex should look like: (\\*[^&])|(\\*$)

Simple test code:

var inputs = new[] {
    "Mother*&Mother*&Son",
    "Mother*Mother*&Son",
    "Mother**&Mother*&Son",
    "Mother*&*Mother*&Son",
    "Mother*&Mother*&Son*"
};

var regex = new Regex(@"(\*[^&])|(\*$)");

var isOK = inputs.Select(x => !regex.IsMatch(x)).ToList();

Returns a list of results, which contains true , false , false , false , false .

For something like this, I'd favor the direct approach, rather than using Regex. This will make at most one pass through the entire string, which should be more efficient than a Regex.

/// Return true if every instance of 'a' in the string is followed by 'b'. 
/// Also returns true if there are no instances of 'a' in the string.
/// Returns false if there exists any 'a' that is not followed by 'b'.
public static bool IsTwoCharSequence(string s, char a, char b)
{
    if(String.IsNullOrEmpty(s)) return true;
    if(s[s.Length - 1] == a) return false; // ends in a, not followed by b. Condition failed.

    int index = s.IndexOf(a); // find the first a
    while(index != -1)
    {
        if(s[index + 1] != b) return false; // a not followed by b.
        index = s.IndexOf(a, index + 1);
    }

    return true; // either no a, or all a followed by b.
}

Edit: In addition, you don't need to worry about how to quote your separator characters, when they're also special characters within a Regex.


Edit 2: Yes, it's two loops, but look at what each loop is doing.

The inner loop, the one inside of String.IndexOf, will iterate through characters until it finds the passed-in character. The first call to IndexOf (the one outside the while loop) starts searching at the beginning of the string, and the subsequent ones start at that index, and continue searching to the next match, or to the end. Overall, we've made just one pass over the entire string.

Here's another method, which is similar in concept to the above one, but where the 'iterate the entire string only once' is more explicit.

public static bool IsTwoCharSequence(string s, char a, char b)
{
    if (String.IsNullOrEmpty(s)) return true;

    bool foundA = false;

    foreach (char c in s)
    {
        if (foundA && c == b)
            foundA = false;
        else if (foundA)
            return false;
        else if (c == a)
            foundA = true;
    }

    if (foundA) return false; // 'a' was the last char in the string.

    return true;
}

Use Regular expressions and check that the number of matches for *& is the same as the number of *s

code of the top of my head, may not compile but try:

Regex r = new Regex(@"\*&");
Regex r2 = new Regex(@"\*");
if (r.Matches(myString).Count == r2.Matches(myString).Count) //success!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM