在C ++ / CLI中捕获组

时间:2014-05-02 17:11:45

标签: .net regex c++-cli

您好我正在尝试使用C ++ / CLI中的regex从更大的字符串中捕获子字符串 这是代码:

System::String^ str_path = "C:\\users\\Downloads\\myfile.pl";
Regex^ pat_scriptname = gcnew Regex("(.[^\.]*)\.pl");
Match^ scrpt_name = pat_scriptname->Match(str_path);
System::String^ filename = scrpt_name->Value;

这里我只想捕获子字符串“myfile”...但它不起作用, filename中保存的输出始终为“myfile.pl”

2 个答案:

答案 0 :(得分:2)

如果没有代码更改,您可以使用以下正则表达式:[^\\]+(?=\.pl$),在C ++中必须将其写为[^\\\\]+(?=\\.pl$)

Regular expression visualization

Debuggex Demo

另一个问题,为什么要使用正则表达式?为什么不使用以下代码?

System::String^ filename = System::IO::Path::GetFileNameWithoutExtension(str_path);

答案 1 :(得分:1)

有几件事:

首先,您需要更多反斜杠。 C ++ / CLI中的\.正在转义句点,而不是在字符串中插入反斜杠。 (你在路径中做得很好,不要忘记在正则表达式中这样做。)注意编译器在这里给你一个警告:warning C4129: '.' : unrecognized character escape sequence

gcnew Regex("(.[^\\.]*)\\.pl");
                 ^^    ^^

其次,在[]内,我假设你想匹配句点和反斜杠以外的所有字符。阅读"[^\\.]",它将匹配除句点之外的所有字符。 (反斜杠正在逃避正则表达式中的句点,使其成为明确的句号而不是任何字符。)因此,我们需要同时避开反斜杠和句号。

gcnew Regex("(.[^\\\\\\.]*)\\.pl");
                 ^^  ^^ escape the period
                 ^^ escape the backslash

你说你希望输出为myfile。使用前导.,它匹配myfile之前的反斜杠,所以让我们摆脱它。

gcnew Regex("([^\\\\\\.]*)\\.pl");

现在,呼叫->Value。这最终得到了我们Group[0]->Value,这是匹配的完整正则表达式。引用Match.Groups

  

如果正则表达式引擎可以找到匹配项,则Groups属性返回的GroupCollection对象的第一个元素包含与整个正则表达式模式匹配的字符串。如果正则表达式包括捕获组,则每个后续元素表示捕获的组。

因为我们想要第一个被捕获的组:

String^ filename = scrpt_name->Groups[1]->Value;

最终代码:

String^ str_path = "C:\\users\\Downloads\\myfile.pl";
Regex^ pat_scriptname = gcnew Regex("([^\\\\\\.]*)\\.pl");
Match^ scrpt_name = pat_scriptname->Match(str_path);
String^ filename = scrpt_name->Groups[1]->Value;

Debug::WriteLine(filename);

输出:

myfile