Frage

Hi i am trying to capture a substring from a bigger string using regex in C++/CLI Here is the Code:

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;

Here i just want to capture the substring "myfile" only ...but it is not working, The output saved in filename is always "myfile.pl"

War es hilfreich?

Lösung

Without code change you can just use the following regex: [^\\]+(?=\.pl$), in C++ it has to be written as [^\\\\]+(?=\\.pl$)

Regular expression visualization

Debuggex Demo

Another question, why do you use regex for it? Why not the following code?

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

Andere Tipps

There's a couple things:

First, you need more backslashes. \. in C++/CLI is escaping the period, not inserting a backslash into the string. (You did it right in the path, don't forget to do it in the regex.) Note that the compiler is giving you a warning here: warning C4129: '.' : unrecognized character escape sequence.

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

Second, inside the [], I assume you want to match all characters other than period and backslash. With it reading "[^\\.]", it will match all characters other than a period. (The backslash is escaping the period in the Regex, making it an explicit period instead of any character.) Therefore, we need to escape both the backslash and the period.

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

You said you wanted the output to be myfile. With that leading ., it's matching the backslash just before myfile, so let's get rid of that.

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

Now, the call to ->Value. That ends up getting us Group[0]->Value, which is the full regular expression that was matched. Quoting Match.Groups:

If the regular expression engine can find a match, the first element of the GroupCollection object returned by the Groups property contains a string that matches the entire regular expression pattern. Each subsequent element represents a captured group, if the regular expression includes capturing groups.

Since we want the first captured group:

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

Final code:

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);

Output:

myfile
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top