Сопоставить и разбить строку с регулярным выражением - PullRequest
2 голосов
/ 16 апреля 2011

Я хочу проверить входную строку по регулярному выражению, а затем разделить ее.

Входная строка может быть любой комбинацией буквы A и буквы A, за которыми следует восклицательный знак. Например, это допустимые строки ввода: A, A !, AA, AA !, A! A, A! A !, AAA, AAA !, AA! A, A! AA, ... Любые другие символы должны приводить к недопустимым матч.

Мой код, вероятно, будет выглядеть примерно так:

public string[] SplitString(string s)
{
    Regex regex = new Regex(@"...");
    if (!regex.IsMatch(s))
    {
        throw new ArgumentException("Wrong input string!");
    }

    return regex.Split(s);
}

Как должно выглядеть мое регулярное выражение?

Редактировать - некоторые примеры:

  • входная строка «AAA», функция должна возвращать массив из 3 строк («A», «A», «A»)
  • входная строка «A! AAA!», Функция должна возвращать массив из 4 строк («A!», «A», «A», «A!»)
  • входная строка "AA! B", функция должна выдавать ArgumentException

Ответы [ 5 ]

2 голосов
/ 16 апреля 2011

Не похоже, что Regex - это хороший план.Взгляните на это:

private bool ValidString(string myString)
{
    char[] validChars = new char[] { 'A', '!' };
    if (!myString.StartsWith("A"))
        return false;
    if (myString.Contains("!!"))
        return false;
    foreach (char c in myString)
    {
        if (!validChars.Contains(c))
            return false;
    }
    return true;
}

private List<string> SplitMyString(string myString)
{
    List<string> resultList = new List<string>();
    if (ValidString(myString))
    {
        string resultString = "";
        foreach (char c in myString)
        {
            if (c == 'A')
                resultString += c;
            if (c == '!')
            {
                resultString += c;
                resultList.Add(string.Copy(resultString));
                resultString = "";
            }
        }
    }
    return resultList;
}

Причина, по которой Regex не является хорошим планом, заключается в том, что вы можете написать логику в нескольких простых операторах if, которые компилируются и функционируют намного быстрее и дешевле.Также Regex не так хорош в повторении шаблонов для строки неограниченной длины.Вы либо в конечном итоге напишите длинное регулярное выражение, либо что-то неразборчивое.

EDIT В конце моего кода у вас будет либо List<string> с разделенной строкой ввода, как в вашем вопросе.Или пустой List<string>.Вы можете немного изменить его, чтобы создать исключение ArgumentException, если это требование очень важно для вас.В качестве альтернативы вы можете сделать Count в списке, чтобы увидеть, был ли он успешным.

2 голосов
/ 16 апреля 2011
 Regex regex = new Regex(@"^(A!|A)+$");   

Редактировать:

Использовать что-то вроде http://gskinner.com/RegExr/ для игры с регулярными выражениями

Редактировать после комментария:

Хорошо, вы сделали этонемного более ясно, что вы хотите.Не подходи так.Потому что в том, что вы делаете, вы не можете ожидать совпадения со всем входом, а затем разделить, как это будет весь ввод.Либо используйте отдельное регулярное выражение для разделяемой части, либо используйте группы для получения соответствующих значений.

Пример:

        //Initial match part

        Regex regex2 = new Regex(@"(A!)|(A)");

        return regex2.Split(s);

И снова регулярные выражения не всегда являются ответом.Посмотрите, как это может повлиять на ваше приложение.

1 голос
/ 17 апреля 2011

Я думаю У меня есть решение, которое удовлетворяет всем примерам. Мне пришлось разбить его на два регулярных выражения (которые мне не нравятся) ...

public string[] SplitString(string s)
{
  Regex regex = new Regex(@"^[A!]+$");
  if (!regex.IsMatch(s))
  {
      throw new ArgumentException("Wrong input string!");
  } 
  return Regex.Split(s, @"(A!?)").Where(x => !string.IsNullOrEmpty(x)).ToArray();
}

Обратите внимание на использование linq - требуется для удаления пустых совпадений.

1 голос
/ 16 апреля 2011

((A+!?)+)

Попробуйте обратиться к Espresso http://www.ultrapico.com/Expresso.htm или Rad Regular Expression Designer http://www.radsoftware.com.au/regexdesigner/ для разработки и тестирования RE.

1 голос
/ 16 апреля 2011

Вы можете попробовать что-то вроде:

Regex regex = new Regex(@"^[A!]+$");
...