Как выбрать совпадение с регулярным выражением по произвольному индексу? - PullRequest
0 голосов
/ 19 июля 2010

У меня есть строка, которая выглядит следующим образом:

ABC-DEF01-GHI54677-JKL! 9988-MNOP

Между каждым - может находиться практически любой символповторяется любое количество раз.

Я использую это регулярное выражение:

[^-]*

Как мне сделать так, чтобы оно совпадало с совпадением по 2-му индексу (например, DEF01)?Или 3-й (GHI54677) или 4-й (JKL! 9988)?

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

Ответы [ 3 ]

2 голосов
/ 19 июля 2010

Второй набор паренов будет захватывать «DEF», «GHI» и «JKL» соответственно ...

([^-]+-){1}([^-]+)
([^-]+-){2}([^-]+)
([^-]+-){3}([^-]+)

Если это perl, сделать первый набор паренов неперехваченным, т.е.:

# perl -de 0
$_="ABC-DEF-GHI-JKL-MNO"
p /(?:[^-]+-){1}([^-]+)/
  DEF
p /(?:[^-]+-){2}([^-]+)/
  GHI
p /(?:[^-]+-){3}([^-]+)/
  JKL

$_="ABC-DEF01-GHI54677-JKL!9988-MNOP"
p /(?:[^-]+-){1}([^-]+)/
  DEF01
p /(?:[^-]+-){2}([^-]+)/
  GHI54677
p /(?:[^-]+-){3}([^-]+)/
  JKL!9988

Объяснение:

(?:  = non-capturing parens
[^-] = a non-dash character
+    = one or more
-    = a dash
)    = close paren
{3}  = repeat 3 times

Эта часть «сожирает» 1, 2, 3 или любое другое число блоков, оставляя следующий набор равнымвозьмите тот, который вы ищете.

Вместо + вы также можете использовать {1,}, что означает 1-к-любому-номеру.

Если ваши блоки могут быть нулевымиразмер, так:

ABC - GHI-JKL

И вы хотите найти второе, это "" (пустая строка), затем используйте * вместо +.Или вы можете использовать {0,}, что означает от 0 до любого числа.

1 голос
/ 19 июля 2010

Вы не указали, какой язык / механизм регулярных выражений вы используете, но некоторые (большинство?) Позволяют вам многократно применять совпадение к одной и той же строке. Например, pcrecpp позволяет вам сделать:

pcrecpp::StringPiece piece("ABC-DEF-GHI-JKL-MNO");
pcrecpp::RE re("([^-]+)-?");
unsigned int index = 3; // e.g., for GHI

std::string group;
for(unsigned int i = 0; i < index; i++)
    re.Consume(&piece, &group);

// group now contains "GHI". Calling Consume again would give it JKL
0 голосов
/ 19 июля 2010

Другой ответ в зависимости от вашей ревизии: Вы просто хотите это?

(?:[^-]+-){index-1}([^-]+)

Группа без захвата соответствует index-1 субблоков, поэтому для index=3 она соответствует ABC-DEF01-тогда группа захвата соответствует GHI54677

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