Regex: Get Filename Without Extension in One Shot? - regex

I want to get just the filename using regex, so I've been trying simple things like
([^\.]*)
which of course work only if the filename has one extension. But if it is adfadsfads.blah.txt I just want adfadsfads.blah. How can I do this with regex?
In regards to David's question, 'why would you use regex' for this, the answer is, 'for fun.' In fact, the code I'm using is simple
length_of_ext = File.extname(filename).length
filename = filename[0,(filename.length-length_of_ext)]
but I like to learn regex whenever possible because it always comes up at Geek cocktail parties.

Try this:
(.+?)(\.[^.]*$|$)
This will:
Capture filenames that start with a dot (e.g. .logs is a file named .logs, not a file extension), which is common in Unix.
Gets everything but the last dot: foo.bar.jpeg gets you foo.bar.
Handles files with no dot: secret-letter gets you secret-letter.
Note: as commenter j_random_hacker suggested, this performs as advertised, but you might want to precede things with an anchor for readability purposes.

Everything followed by a dot followed by one or more characters that's not a dot, followed by the end-of-string:
(.+?)\.[^\.]+$
The everything-before-the-last-dot is grouped for easy retrieval.
If you aren't 100% sure every file will have an extension, try:
(.+?)(\.[^\.]+$|$)

how about 2 captures one for the end and one for the filename.
eg.
(.+?)(?:\.[^\.]*$|$)

^(.*)\\(.*)(\..*)$
Gets the Path without the last \
The file without extension
The the extension with a .
Examples:
c:\1\2\3\Books.accdb
(c:\1\2\3)(Books)(.accdb)
Does not support multiple . in file name
Does support . in file path

I realize this question is a bit outdated, however, I had some trouble finding a good source and wound up making the regex myself. To save whoever may find this time,
If you're looking for a ~standalone~ regex
This will match the extension without the dot
\w+(?![\.\w])
This will always match the file name if it has an extention
[\w\. ]+(?=[\.])

Ok, I am not sure why I would use regular expression for this. If I know for example that the string is a full filepath, then I would use another API to get the file name. Regular expressions are very powerfull but at the same time quite complex (you have just proved that by asking how to create such a simple regex). Somebody said: you had a problem that you decided to solve it using regular expressions. Now you have two problems.
Think again. If you are on .NET platform for example, then take a look at System.IO.Path class.

I used this pattern for simple search:
^\s*[^\.\W]+$
for this text:
file.ext
fileext
file.ext.ext
file.ext
fileext
It finds fileext in the second and last lines.
I applied it in a text tree view of a folder (with spaces as indents).

Just the name of the file, without path and suffix.
^.*[\\|\/](.+?)\.[^\.]+$

Try
(?<=[\\\w\d-:]*\\)([\w\d-:]*)(?=\.[\.\w\d-:]*)
Captures just the filename of any kind within an entire filepath. Purposefully excludes the file path and the file extension
Etc:
C:\Log\test\bin\fee105d1-5008-410c-be39-883e5e40a33d.pdf
Doesn't capture (C:\Log\test\bin)
Captures (fee105d1-5008-410c-be39-883e5e40a33d)
Doesn't capture (.pdf)

This RegExp works for me:
(.+(?=\..+$))|(.+[^\.])
Results (bold means match):
test.txt
test 234!.something123
.test
.test.txt
test.test2.txt
.

Related

Regular Expression to select everything before and up to a particular text

I am trying to use a regular expression to find a part of a string and select everything up to that string. So for example if my string is this/is/just.some/test.txt/some/other, I want to search for .txt and when I find it select everything before and up to .txt.
After executing the below regex, your answer is in the first capture.
/^(.*?)\.txt/
This matches everything up to ".txt" (without including it):
^.*(?=(\.txt))
You could just do ...
(.*?)\.txt
tested here..
^(.*)text
this worked for me but I was actually trying to get everything after the string too. The first part of the expression should answer your question.
^(.*)text([\s\S]*)$
where ^(.*) takes all before and including the text, while ([\s\S]*)$ takes all after and including the text. Tested it at regexr.com/6cpqg.
References:
above answers among other online sources
https://regexland.com/regex-match-after-character/
Up to and including txt you would need to change your regex like so:
^(.*?\\.txt)
((\n.*){0,3})(.*)\W*\.txt
This will select all the content before the particular word ".txt" including any context in different lines up to 3 lines

regex to get portion of file name after last dot without file extension

I have a bunch of files, some examples are as follows:
/foo1/foo2/bar1.bar2.bar3.answer.jar
/foo1/bar1.bar2.answer.jar
/foo1/foo2/answer.jar
and for all of the above I would like a regex that matches 'answer'. In other words, I'm looking to get an alias for the file that is the portion of the file name after the last dot (or the file name itself if there are no dots) with the file extension (.jar can be guaranteed here to make it simpler) stripped off.
I know I can do this with a more simple regex to split the value up by dots and then get the second last one, but in this case I'm building a back-end thing that will ideally take a regex that is defined in a configuration definition for the given file type, and spit out the alias, which might be different for other file types.
Yep, I'm over-engineering. :)
Any ideas?
Following regex should work for you:
[^/.]+(?=\.jar$)
If using Javascript or a similar flavor where / is regex delimiter then you need to escape / like this:
[^\/.]+(?=\.jar$)
You can use the following regexp: (assuming that the answer part doesn't contain . or /)
[/\.]([^/\.]+)\.jar
The first capturing group is the part what you want to.

How do you find a "."?

I'm trying to create a regular expression to look for filenames from full file paths, but it should not return for just a directory. For example, C:\Users\IgneusJotunn\Desktop\file.doc should return file.doc while C:\Users\IgneusJotunn\Desktop\folder should find no matches. These are all Word or Excel files, but I prefer not to rely on that. This:
StringRegExp($string, "[^\\]*\z",1)
finds whatever is after the last slash, but can't differentiate files from folders. This:
StringRegExp($string, "[^\\]*[dx][ol][cs]\z",1)
almost works, but is an ugly hack and there may be docx or xlsx files. Plus, files could be named like MyNamesDoc.doc. Easily solved if I could search for a period, but . is a used character (it means any single character except a newline) which does not seem to work with escapes. This:
StringRegExp($ue_string, "[^\\]*\..*\z",1)
should work, finding anything after the last backslash, capturing only something with a period in it. How to incorporate a period? Or any way to just match files?
Edit: Answered my own question. I'm interested in why it wasn't working and if there's a more elegant solution.
Local $string = StringRegExp($string, "[^\\]*\.doc\z|[^\\]*\.docx\z|[^\\]*\.xls\z|[^\\]*\.xlsx\z",1)
Periods do in fact work with the same escape slash most special characters use. As for the document type, an Or pipe and a different extension works great. If for some reason you need to add an extension, just add another Or.
Meh, I'm bored. You could do this:
$sFile = StringRegExp($sPath, "[^\\]+\.(?:doc|xls)x?$", 1)
There's no guarantees that a folder wouldn't be named that, so to be absolutely certain you'd have to check the file/folder attributes. However it's doubtful anyone would name a folder with something like '.docx'
Reverse the string.
Look for the "."
Look for "\" with StringInStr (and/or "/")
Trim the right side from the return of StringinStr
Reverse it again.

hgignore: help ignoring all files but certain ones

I need an .hgdontignore file :-) to include certain files and exclude everything else in a directory. Basically I want to include only the .jar files in a particular directory and nothing else. How can I do this? I'm not that skilled in regular expression syntax. Or can I do it with glob syntax? (I prefer that for readability)
Just as an example location, let's say I want to exclude all files under foo/bar/ except for foo/bar/*.jar.
The answer from Michael is a fine one, but another option is to just exclude:
foo/bar/**
and then manually add the .jar files. You can always add files that are excluded by an ignore rule and it overrides the ignore. You just have to remember to add any jars you create in the future.
To do this, you'll need to use this regular expression:
foo/bar/.+?\.(?!jar).+
Explanation
You are telling it what to ignore, so this expression is searching for things you don't want.
You look for any file whose name (including relative directory) includes (foo/bar/)
You then look for any characters that precede a period ( .+?\. == match one or more characters of any time until you reach the period character)
You then make sure it doesn't have the "jar" ending (?!jar) (This is called a negative look ahead
Finally you grab the ending it does have (.+)
Regular expressions are easy to mess up, so I strongly suggest that you get a tool like Regex Buddy to help you build them. It will break down a regex into plain English which really helps.
EDIT
Hey Jason S, you caught me, it does miss those files.
This corrected regex will work for every example you listed:
foo/bar/(?!.*\.jar$).+
It finds:
foo/bar/baz.txt
foo/bar/baz
foo/bar/jar
foo/bar/baz.jar.txt
foo/bar/baz.jar.
foo/bar/baz.
foo/bar/baz.txt.
But does not find
foo/bar/baz.jar
New Explanation
This says look for files in "foo/bar/" , then do not match if there are zero or more characters followed by ".jar" and then no more characters ($ means end of the line), then, if that isn't the case, match any following characters.
Anyone that wants to use negative lookaheads (or ?! in regex syntax) or any kind of back-referencing mechanism should be aware that Mercurial will fall back from google's RE2 to Python's re module for matching.
RE2 is a non-backtracking engine that guarantees a run-time linear with the size of the input. If performance is important to you, that is if you have a big repository, you should consider sticking to more simple patterns that Re2 supports, which is why I think that the solution offered by Ryan.

replace urls

I have a huge txt file and Editpad Pro list of urls with images on the root folder.
http://www.othersite.com/image01.jpg
http://www.mysite.com/image01.jpg
http://www.mysite.com/category/image01.jpg
How can I change only that ones that has images on the root using regexp?
http://www.othersite.com/image01.jpg
http://www.NEW_WEBSITE.com/image01.jpg
http://www.mysite.com/category/image01.jpg
I'm using the RegExr online app.
Search and replace (case insensitive, regular expression):
http://www\.mysite\.com/([^/]*\.(?:jpg|gif|png))
with:
http://www\.NEW_WEBSITE\.com/\1
EDIT
And yes, this will also re-base files such as http://www.mysite.com/.jpg, if any such files or directories exist. If anyone doesn't like this then just replace * with + -- or with {X,} if your assumption happens to be that an image file needs at least a X character name s etc. etc. -- but really, this is probably quite outside the scope of what lab72 is trying to achieve (i.e. not image file name validation.)
url1.replace(/((https?:\/\/www.?)(\w*?)(.com\/image\d*?\.(png|gif|jpg))/,
"$1newName$3");
Something like the above should work. The code is in AS (not compiled though :P) Note that $2 matches the sites name which we are replacing with yoursite.
Replace
http://www\.mysite\.com/image(.*)
with
http://www.newsite.com/image$1
That being said, you might also be interested in a decent text editor. That flash applet is really yucky. You can still use the same regexp, although you'll have to replace the dollar sign $ with a backslash \.