簡體   English   中英

從單個正則表達式匹配文件名和文件擴展名

[英]Match filename and file extension from single Regex

我相信這一定很容易,但我正在努力......

var regexFileName = /[^\\]*$/; // match filename
var regexFileExtension = /(\w+)$/; // match file extension

function displayUpload() {
    var path = $el.val(); //This is a file input
    var filename = path.match(regexFileName); // returns  file name
    var extension = filename[0].match(regexFileExtension); // returns extension

    console.log("The filename is " + filename[0]);
    console.log("The extension is " + extension[0]);
}

上面的函數工作正常,但我確信必須可以通過引用使用 .match() 方法返回的數組的不同部分,使用單個正則表達式來實現。 我試過結合這些正則表達式但沒有成功。

另外,我沒有在示例中使用字符串來測試它,因為 console.log() 轉義了文件路徑中的反斜杠,它開始讓我感到困惑:)

假設所有文件都有擴展名,您可以使用

var regexAll = /[^\\]*\.(\w+)$/;

然后你可以做

var total = path.match(regexAll);
var filename = total[0];
var extension = total[1];

/^.*\\/(.*)\\.?(.*)$/g后面的第一組是你的文件名,第二組是擴展名。

var myString = "filePath/long/path/myfile.even.with.dotes.TXT";
var myRegexp = /^.*\/(.*)\.(.*)$/g;
var match = myRegexp.exec(myString);
alert(match[1]);  // myfile.even.with.dotes
alert(match[2]);  // TXT

即使您的文件名包含多個點或根本不包含點(沒有擴展名),這也有效。
編輯:
這是針對 linux,對於 windows 使用這個/^.*\\\\(.*)\\.?(.*)$/g (在 linux 目錄分隔符是/在 windows 是\\

為此,您可以在正則表達式中使用組:

var regex = /^([^\\]*)\.(\w+)$/;
var matches = filename.match(regex);

if (matches) {
    var filename = matches[1];
    var extension = matches[2];
}

這甚至會識別/home/someUser/.aaa/.bb.c

function splitPathFileExtension(path){
    var parsed = path.match(/^(.*\/)(.*)\.(.*)$/);
    return [parsed[1], parsed[2], parsed[3]];
}

我知道這是一個老問題,但這里有另一種解決方案,它可以處理名稱中的多個點,也可以在根本沒有擴展名(或只有“.”的擴展名)時處理:
/^(.*?)(\\.[^.]*)?$/

一次取一塊:
^
錨定到字符串的開頭(以避免部分匹配)

(.*?)
匹配任何字符. , 0 次或更多次* , 懶惰? (如果后面的可選擴展名可以匹配,不要只抓取它們),並將它們放在第一個捕獲組( )

(\\.
使用(為擴展啟動第二個捕獲組。該組以文字.字符開頭(我們用\\轉義,這樣.不會被解釋為“匹配任何字符”)。

[^.]*
定義一個字符集[] 通過指定這是一個倒置字符集^來匹配不在集合中的字符。 匹配 0 個或多個非. 字符以獲取文件擴展名的其余部分* 我們以這種方式指定它,這樣它就不會與foo.bar.baz文件名早期匹配,錯誤地給出了一個包含多個點的擴展名.bar.baz而不僅僅是.baz . 不需要在[]內轉義,因為所有內容(除了^ )都是字符集中的文字。

)?
結束第二個捕獲組)並表明整個組是可選的? ,因為它可能沒有擴展名。

$
錨定到字符串的末尾(再次,避免部分匹配)

如果您使用的是 ES6,您甚至可以使用析構來獲取 1 行中的結果:
[,filename, extension] = /^(.*?)(\\.[^.]*)?$/.exec('foo.bar.baz'); 它給出的文件名是'foo.bar' ,擴展名是'.baz'
'foo'給出'foo' and ''
'foo.' 給出'foo''.'
'.js'給出'''.js'

我認為這是一個更好的方法,因為只匹配有效的目錄、文件名和擴展名。 並對路徑、文件名和文件擴展名進行分組。 並且也僅適用於空路徑文件名。

^([\w\/]*?)([\w\.]*)\.(\w)$

測試用例

the/p0090Aath/fav.min.icon.png
the/p0090Aath/fav.min.icon.html
the/p009_0Aath/fav.m45in.icon.css
fav.m45in.icon.css
favicon.ico

輸出

[the/p0090Aath/][fav.min.icon][png]
[the/p0090Aath/][fav.min.icon][html]
[the/p009_0Aath/][fav.m45in.icon][css]
[][fav.m45in.icon][css]
[][favicon][ico]

(?!\\w+).(\\w+)(\\s)

查找一個或多個單詞 (s) \\w+ ,否定(?! )以便結果中不顯示單詞 (s),指定分隔符. , 找到第一個單詞(\\w+)並忽略可能的空格(\\s)之后的單詞

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM