Разбор строки в C #; есть ли более чистый путь? - PullRequest
5 голосов
/ 08 апреля 2009

C #, .NET 3.5

Для меня это просто пахнет ужасно, но я не могу придумать другого пути.

Учитывая строку с форматом «Джо Смит (jsmith)» (без кавычек), я бы хотел разобрать только строку «jsmith» в скобках. Я придумал это:

private static string DecipherUserName( string user )
{
    if( !user.Contains( "(" ) )
        return user;

    int start = user.IndexOf( "(" );

    return user.Substring( start ).Replace( "(", string.Empty ).Replace( ")", string.Empty );
}

Кроме моего (не) здорового отвращения к RegEx, есть ли более простой способ разобрать подстроку?

Edit: Чтобы уточнить, строка для анализа всегда будет иметь вид: «Джо Смит (jsmith)» (без кавычек).

Ответы [ 6 ]

20 голосов
/ 08 апреля 2009

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

Одно регулярное выражение, которое будет работать, это "\ w + \ ((. *) \)" - jsmith будет в Match.Groups [1].

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

9 голосов
/ 08 апреля 2009

Вам не нужна первая замена, так как вы можете просто добавить 1 в позицию "(".

private static string DecipherUserName (string user) {           
    int start = user.IndexOf( "(" );
    if (start == -1)
        return user;
    return user.Substring (start+1).Replace( ")", string.Empty );
}
5 голосов
/ 08 апреля 2009

Если строка пользователя всегда имеет форму «Джо Смит (jsmith)», это должно работать.

private static string DecipherUserName(string user)
{
    string[] names = user.Split(new char[] {'(', ')'});
    return names.Length > 2 ? names[1] : user;
}

И если пользовательская строка всегда "Джо Смит (jsmith)", это всегда будет работать.

private static string DecipherUserName(string user)
{
    return "jsmith";
}

Вторая запись только для юмора.

5 голосов
/ 08 апреля 2009

Вид хака ... ^^

return user.Substring(user.IndexOf('(') + 1).TrimEnd(')');

Если user не содержит открывающих скобок, IndexOf() возвращает -1, мы добавляем единицу, получаем ноль, а SubString() возвращает всю строку. TrimEnd() не будет иметь эффекта, если имя пользователя не заканчивается закрывающей скобкой.

Если user содержит открывающую скобку, IndexOf() возвращает ее индекс, мы пропускаем открывающую скобку, добавляя ее, и извлекаем остальную часть строки с помощью Substring(). Наконец, мы удаляем закрывающую скобку с TrimEnd().

2 голосов
/ 08 апреля 2009

Поскольку функция IndexOf будет возвращать -1, когда значение не существует, вы можете сделать что-то немного другое ...

private static string DecipherUserName( string user )
{           
   int start = user.IndexOf( "(" );

   if (start > -1)
   {
      return user.Substring( start ).Replace( "(", string.Empty ).Replace( ")", string.Empty );
   }
   else
   {
      return user;
   }
}
1 голос
/ 08 апреля 2009

Я бы использовал

int start=user.IndexOf('(');
if (start != -1) {
  end = user.IndexOf(')', start);
  return user.Substring(start+1,end-start-1);
} else
  return user;

Но это просто косметическое изменение: использование символов в IndexOf немного быстрее, а использование метода Substring, кажется, более точно выражает, что должно быть сделано (и этот метод более надежен, если у вас несколько пар скобок). ..)

Тем не менее, Метод Daniel L (использующий String.Split) может быть проще (но он не очень хорошо справляется с некорректными строками и должен создавать массив строк).

В общем, я бы посоветовал вам преодолеть отвращение к регулярным выражениям, поскольку именно эта ситуация и предназначена для них :-) ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...