我有一个看起来像的字符串:
ABC-DEF01-GHI54677-JKL!9988-MNOP
每个-
之间几乎可以重复任何次数的任何字符。
我正在使用这个正则表达式:
[^-]*
如何让它与第二个索引(例如DEF01)的匹配“匹配”?或第3(GHI54677)或第4(JKL!9988)?
我正在使用的引擎不允许我指定匹配索引或其他代码 - 它必须在表达式中完成。
答案 0 :(得分:2)
第二组parens将分别捕获“DEF”,“GHI”和“JKL”......
([^-]+-){1}([^-]+)
([^-]+-){2}([^-]+)
([^-]+-){3}([^-]+)
如果这是perl,则使第一组parens不捕获,即:
# 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 :(得分:1)
您没有指定您正在使用的语言/正则表达式引擎,但有些(大多数?)允许您反复将匹配反复应用于同一个字符串。例如,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
答案 2 :(得分:0)
基于您的修订的不同答案:您只想要这个吗?
(?:[^-]+-){index-1}([^-]+)
非捕获组匹配子块的index-1
,因此index=3
匹配ABC-DEF01-
,然后捕获组匹配GHI54677