Возврат только части совпадения из регулярного выражения - PullRequest
19 голосов
/ 10 марта 2009

Скажем, у меня есть строка "Имя пользователя: имя_фамилия.символ", содержащаяся в большей строке. Как я могу использовать регулярное выражение, чтобы просто получить часть имени_символа?

Каждый метод, который я пробовал, возвращает строку «Имя пользователя: имя.фамилия», затем я должен заменить строку «Имя пользователя:» на пустую строку.

Могут ли здесь быть полезны обратные ссылки?

Edit:

Более длинная строка может содержать «Account Name: firstname.surname», поэтому я хочу сопоставить часть «User Name:» строки, а также просто получить это значение.

Ответы [ 4 ]

32 голосов
/ 10 марта 2009

Мне нравится использовать именованные группы:

Match m = Regex.Match("User Name:first.sur", @"User Name:(?<name>\w+\.\w+)");
if(m.Success)
{
   string name = m.Groups["name"].Value;
}

Помещение ?<something> в начале группы в скобках (например, (?<something>...)) позволяет получить значение из совпадения, используя something в качестве ключа (например, из m.Groups["something"].Value)

Если вы не хотите называть свои группы, вы можете сказать

Match m = Regex.Match("User Name:first.sur", @"User Name:(\w+\.\w+)");
if(m.Success)
{
   string name = m.Groups[1].Value;
}

и просто получите первое, что соответствует. (Обратите внимание, что первая заключенная в скобки группа находится в индексе 1; все совпадающее выражение - в индексе 0)

6 голосов
/ 21 августа 2009

Вы также можете попробовать концепцию «lookaround». Это своего рода утверждение нулевой ширины, означающее, что оно будет соответствовать символам, но не будет захватывать их в результате.

В вашем случае мы могли бы взглянуть позитивно: мы хотим, чтобы то, что находится за целевой строкой "firstname.surname", было равно "User Name:".

Оператор положительного просмотра: (? <= StringBehind) StringWeWant </p>

Это может быть достигнуто, например, так (небольшой пример на Java с использованием замены строки):

String test = "Account Name: firstname.surname; User Name:firstname.surname";
String regex = "(?<=User Name:)firstname.surname";
String replacement = "James.Bond";
System.out.println(test.replaceAll(regex, replacement));

Это заменяет только строки «firstname.surname», которым предшествует «User Name:», без замены самого «User Name:», которое не возвращается регулярным выражением, только сопоставляется.

ВЫХОД: имя учетной записи: имя.фамилия; Имя пользователя: James.Bond

То есть, если используемый вами язык поддерживает такие операции

3 голосов
/ 10 марта 2009

Создайте группу с парантезами, затем возьмите ее из коллекции Match.Groups, например:

string s = "User Name:firstname.surname";
Regex re = new Regex(@"User Name:(.*\..*)");
Match match = re.Match(s);
if (match.Success)
{
    MessageBox.Show(match.Groups[1].Value);
}

(примечание: первая группа с индексом 0 - это полное совпадение)

2 голосов
/ 10 марта 2009

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

Итак, ваше регулярное выражение может выглядеть так: Имя пользователя: ([^.]. [^.])

Полное совпадение - группа 0. Часть, соответствующая скобкам, - группа 1.

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