Matching characters reversely using regex
i need a regex that matches a string from specified position to first character reversely. strings are some file names.
- i m using Delphi 2010
- my example string is New Document.extension
- if specified position is 4, it should match: New Docu
You can get from "New Document.extension" to "New docu" following those steps:
- First strip the extension. You end up with "New Document"
- Remove the last 4 characters. You get "New Docu".
For the "This Is My Longest Document.ext1.ext2" example:
- Strip the extension, you end up with: "This Is My Longest Document.ext1"
- Strip the last 4 characters. You get: "Thi开发者_如何学编程s Is My Longest Document."
So you want the entire string up to the fourth-to-last position before the final dot? No problem:
Delphi .NET:
ResultString := Regex.Match(SubjectString, '^.*(?=.{4}\.[^.]*$)').Value;
Explanation:
^ # Start of string
.* # Match any number of characters
(?= # Assert that it's possible to match, starting at the current position:
.{4} # four characters
\. # a dot (the last dot in the string!) because...
[^.]* # from here one only non-dots are allowed until...
$ # the end of the string.
) # End of lookahead.
Since I can't post the regex because I came up with the exact same Regex as Tim, I'm going to post a piece of procedural code that does the exact same thing.
function FileNameWithoutExtension(const FileName:string; const StripExtraNumChars: Integer): string;
var i: Integer;
begin
i := LastDelimiter('.', FileName); // The extension starts at the last dot
if i = 0 then i := Length(FileName) + 1; // Make up the extension position if the file has no extension
Dec(i, StripExtraNumChars + 1); // Strip the requested number of chars; Plus one for the dot itself
Result := Copy(FileName, 1, i); // This is the result!
end;
You accepted the answer giving a regex for
The entire string up to the fourth-to-last position before the final dot.
If that's what you want then you do it best without a regex:
procedure RemoveExtensionAndFinalNcharacters(var s: string; N: Integer);
begin
s := ChangeFileExt(s, '');//remove extension
s := Copy(s, 1, Length(s)-N);//remove final N characters
end;
This more efficient than a regex and, much more importantly, it is much clearer and more intelligible.
Regexes are not the only fruit.
Edit based on comments
I'm not sure how Delphi does regex, but this works in most systems.
^.*(?=.{4}\.\w+$)
^ #the start of the string
.* #Any characters.
(?= #A lookahead meaning followed by...
.{4} #Any 4 chars.
\. #A literal .
\w+ #an actual extension.
$ #the end of the string
) #closing the lookahead
You could also use \w{3}$
instead of \w+
at the end if you wanted to make sure that the extension was three charaters long.
精彩评论