The second set of parens will capture "DEF", "GHI", and "JKL", respectively...
([^-]+-){1}([^-]+)
([^-]+-){2}([^-]+)
([^-]+-){3}([^-]+)
If this is perl, make the first set of parens non-capturing, i.e.:
# 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
Explanation:
(?: = non-capturing parens
[^-] = a non-dash character
+ = one or more
- = a dash
) = close paren
{3} = repeat 3 times
This part "gobbles up" 1, 2, 3, or any number you like, of the blocks, leaving the next set to take the one you're looking for.
In lieu of +
, you can also use {1,}
meaning 1-to-any-number.
If your blocks can be zero size, so:
ABC--GHI-JKL
And you want to find the second, which is "" (empty string), then use *
instead of +
. Or you can use {0,}
, meaning 0-to-any-number.