在我的 Java 應用程式中,我使用 Azure Data Lake Storage Gen2 進行存盤 ( ABFS )。在處理對檔案系統的請求的類中,我得到一個檔案路徑作為輸入,然后使用一些正則運算式從中提取 Azure 連接資訊。
Azure Data Lake Storage Gen2 URI采用以下格式:
abfs[s]://<file_system>@<account_name>.dfs.core.windows.net/<path>/<file_name>
我使用以下正則運算式abfss?://([^/] )@([^\\.] )(\\.[^/] )/?((. )?)來決議要提取的給定檔案路徑:
- 檔案系統
- 帳戶名稱
- 帳號后綴
- 相對路徑(路徑 檔案名)
下面只是一個測驗 Java 代碼,帶有注釋,說明匹配后每個變數中的結果/值。
private void parsePath(String path) {
//path = abfs://[email protected]/selim/test.csv
Pattern azurePathPattern = Pattern.compile("abfss?://([^/] )@([^\\.] )(\\.[^/] )/?((. )?)");
Matcher matcher = azurePathPattern.matcher(path);
if (matcher.find()) {
String fileSystem = matcher.group(1); //storage
String accountName = matcher.group(2); //myaccount
String accountSuffix = matcher.group(3); //.dfs.core.windows.net
//relativePath is <path>/<file_name>
String relativePath = matcher.group(4); //selim/test.csv
}
}
問題是當我決定使用Azurite時,它??是一個與 Azure 存盤 API 兼容的服務器(模擬器),它允許我對此模擬器而不是 Microsoft檔案中推薦的實際 Azure 服務器運行單元測驗。
Azurite 使用與 Azure 不同的檔案 URI,因此這使我上面的 Regex 對測驗目的無效。Azurite 檔案 URI 采用以下格式:
abfs[s]://<file_system>@<local_ip>:<local_port>/<account_name>/<path>/<file_name>
Azurite 默認account_name為devstoreaccount1,因此這里是 Azurite 上檔案的示例路徑:
abfs://[email protected]:10000/devstoreaccount1/selim/test.csv
如果由上面的正則運算式決議,這將是輸出,導致對 Azurite 服務器的錯誤 api 呼叫:
- 檔案系統:存盤(正確)
- accountName:127(不正確,應該是:devstoreaccount1)
- accountSuffix: .0.0.1:10000 (不正確,應該是空字串)
- relativePath: devstoreaccount1/selim/test.csv (不正確,應該是selim/test.csv)
是否有可能有一個可以同時處理 URI 或 2 個正則運算式的 1 個正則運算式來解決這個問題
uj5u.com熱心網友回復:
解決方案 1
您可以為此使用單個模式,但您需要檢查代碼中匹配的組以確定在何處捕獲必要的詳細資訊。
正則運算式看起來像
abfss?://(?:([^@/]*)@(\d{1,3}(?:\.\d{1,3}){3}:\d )/([^/] )|([^/] )@([^.] )(\.[^/] ))(?:/(. ))?
請參閱正則運算式演示。另([^@/]*)@(\d{1,3}(?:\.\d{1,3}){3}:\d )/([^/] )一種方法允許捕獲檔案系統、IP 地址(如在 之后的部分(帶有埠號)@和斜杠之后的帳戶名)。
Java代碼看起來像
import java.util.*;
import java.util.regex.*;
class Test
{
public static void main (String[] args) throws java.lang.Exception
{
Pattern pattern = Pattern.compile("abfss?://(?:([^@/]*)@(\\d{1,3}(?:\\.\\d{1,3}){3}:\\d )/([^/] )|([^/] )@([^.] )(\\.[^/] ))(?:/(. ))?");
String[] inputs = {
"abfs://[email protected]/selim/test.csv",
"abfs://[email protected]:10000/devstoreaccount1/selim/test.csv"
};
for (String s: inputs) {
Matcher matcher = pattern.matcher(s);
if (matcher.find()){
if (matcher.group(5) != null) { // If original URL is found
String fileSystem = matcher.group(4); //storage
String accountName = matcher.group(5); //myaccount
String accountSuffix = matcher.group(6); //.dfs.core.windows.net
String relativePath = matcher.group(7); //selim/test.csv
System.out.println(s ":\nfileSystem: " fileSystem "\naccountName: " accountName "\naccountSuffix: '" accountSuffix "'\nrelativePath:" relativePath "\n-----");
} else { // we have an Azurite URL
String fileSystem = matcher.group(1); //storage
String accountName = matcher.group(3); //devstoreaccount1
String accountSuffix = ""; // empty (or do you need matcher.group(2) to get "127.0.0.1:10000"?)
String relativePath = matcher.group(7); //selim/test.csv
System.out.println(s ":\nfileSystem: " fileSystem "\naccountName: " accountName "\naccountSuffix: '" accountSuffix "'\nrelativePath:" relativePath "\n-----");
}
}
}
}
}
輸出:
abfs://[email protected]/selim/test.csv:
fileSystem: storage
accountName: myaccount
accountSuffix: '.dfs.core.windows.net'
relativePath:selim/test.csv
-----
abfs://[email protected]:10000/devstoreaccount1/selim/test.csv:
fileSystem: storage
accountName: devstoreaccount1
accountSuffix: ''
relativePath:selim/test.csv
解決方案 2
您可以使用兩種不同的正則運算式,如果第一個找不到匹配項,則將嘗試第二個。第一個:
abfss?://([^@/]*)@(\d{1,3}(?:\.\d{1,3}){3}:\d )/([^/] )(?:/(. ))?
請參閱此正則運算式演示。第二個:
abfss?://([^/] )@([^.] )(\.[^/] )(?:/(. ))?
請參閱此正則運算式演示。由于這也匹配第一種型別的 URL,因此您需要確保以固定順序運行它們。
請參閱Java 演示:
import java.util.*;
import java.util.regex.*;
class Test
{
public static void main (String[] args) throws java.lang.Exception
{
Pattern pattern_azurite = Pattern.compile("abfss?://([^@/]*)@(\\d{1,3}(?:\\.\\d{1,3}){3}:\\d )/([^/] )(?:/(. ))?");
Pattern pattern_original = Pattern.compile("abfss?://([^/] )@([^.] )(\\.[^/] )(?:/(. ))?");
String[] inputs = {
"abfs://[email protected]/selim/test.csv",
"abfs://[email protected]:10000/devstoreaccount1/selim/test.csv",
"http://www.blahblah.blah"
};
for (String s: inputs) {
Map<String, String> result = null;
Matcher matcher_azurite = pattern_azurite.matcher(s);
if (matcher_azurite.find()){
result = parseMatchResult(matcher_azurite, new int[] {1, 3, -1, 4});
} else {
Matcher matcher_original = pattern_original.matcher(s);
if (matcher_original.find()){
result = parseMatchResult(matcher_original, new int[] {1, 2, 3, 4});
}
}
if (result != null) { // Now print
for (String key : result.keySet()) {
System.out.println("'" key "': '" result.get(key) "'");
}
System.out.println("----------------");
} else {
System.out.println("No match!");
}
}
}
public static Map<String, String> parseMatchResult(Matcher m, int[] indices) {
Map<String, String> res = new HashMap<String, String>();
res.put("fileSystem", m.group(indices[0]));
res.put("accountName", m.group(indices[1]));
res.put("accountSuffix", indices[2] > -1 ? m.group(indices[2]) : "");
res.put("relativePath", m.group(indices[3]));
return res;
}
}
輸出:
'fileSystem': 'storage'
'accountSuffix': '.dfs.core.windows.net'
'accountName': 'myaccount'
'relativePath': 'selim/test.csv'
----------------
'fileSystem': 'storage'
'accountSuffix': ''
'accountName': 'devstoreaccount1'
'relativePath': 'selim/test.csv'
----------------
No match!
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/431827.html
