2012-01-25 48 views
6

文件擴展名我敢肯定,這一定是很容易的,但我掙扎......匹配文件名,並從單一的正則表達式

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()中逸出的文件路徑反斜線和它已開始在此之後第一次來迷惑我:)

回答

5

假設所有文件確實有一個擴展,你可以使用

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

然後,你可以做

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

我更多的是.NET正則表達式的傢伙,但不你錯過了第一個捕獲組? – rtpHarry

+0

@rtpHarry:整個匹配(組0)是文件名(包括擴展名),第一個捕獲組(組1)是擴展名。 –

+0

他需要文件的名稱,而不是整個路徑。 – shift66

6

/^.*\/(.*)\.?(.*)$/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是\

+0

這個失敗,''的/ tmp/myFile.txt'' – DelightedD0D

2

您可以喲使用組您的正則表達式爲:

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

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

我更像一個.net正則表達式的傢伙,但是你是不是錯過了第一個捕獲組? – rtpHarry

+0

你說得對。我只是對它進行了測試,文檔有點令人困惑:P – fivedigit

+0

您的代碼之前是正確的,現在已被破壞。如果你只有一個捕獲組,那麼'match [2]'應該來自哪裏? –

0

我認爲這是一種更好的方法,因爲只匹配有效的目錄,文件名和擴展名。並將路徑,文件名和文件擴展名分組。並且還可以僅處理空路徑文件名。

^([\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] 
2

這將承認甚至/home/someUser/.aaa/.bb.c

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

我知道這是一個老問題,但在這裏是另一個解決方案,可以在名稱中處理多個點,也當沒有擴展在所有(或者只是一個擴展名爲「」):
/^(.*?)(\.[^.]*)?$/

服用一片在一個時間:
^
錨開始字符串(以避免部分匹配)

(.*?)
匹配任何字符.,0次或更多次*,懶洋洋地?(不只是抓住他們所有,如果以後可選的擴展可以匹配),並把它們放在第一捕獲組()

(\.
啓動第二捕獲組使用(擴展。該組以字面.字符開頭(我們用\轉義,以致.不被解釋爲「匹配任何字符」)。

[^.]*
定義字符集[]。匹配字符不是,通過指定這是一個倒序字符集^。匹配0或更多非.字符以獲得文件擴展名*的其餘部分。我們用這種方式指定它,以便它不匹配foo.bar.baz等文件名,不正確地爲.bar.baz而不是.baz中的多個點擴展。 .不需要在[]內部轉義,因爲所有內容(除^)都是字符集中的文字。

)?
的第2種捕獲組)並表示整個集團是可選?,因爲它可能沒有擴展名。

$
錨字符串的結尾(再次,以避免部分匹配)

如果您使用ES6你甚至可以用自毀搶在1號線的結果:
[,filename, extension] = /^(.*?)(\.[^.]*)?$/.exec('foo.bar.baz'); 這文件名爲'foo.bar',擴展名爲'.baz'
'foo''foo' and ''
'foo.''foo''.'
'.js''''.js'