您好我正在尝试使用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”
答案 0 :(得分:2)
如果没有代码更改,您可以使用以下正则表达式:[^\\]+(?=\.pl$)
,在C ++中必须将其写为[^\\\\]+(?=\\.pl$)
另一个问题,为什么要使用正则表达式?为什么不使用以下代码?
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