![](/img/trans.png)
[英]copy data from on premise sql server to delta format in Azure Data Lake Storage Gen2
[英]Regex to parse Azure Data Lake Storage Gen2 URI for production and testing with Azurite
在我的 Java 应用程序中,我使用 Azure Data Lake Storage Gen2 进行存储 ( ABFS )。 在处理文件系统请求的 class 中,我得到一个文件路径作为输入,然后使用一些正则表达式从中提取 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://storage@myaccount.dfs.core.windows.net/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,因此这使我的上述正则表达式无法用于测试目的。 Azurite 文件 URI 的格式如下:
abfs[s]://<file_system>@<local_ip>:<local_port>/<account_name>/<path>/<file_name>
Azurite 默认account_name
是devstoreaccount1 ,因此这里是 Azurite 上文件的示例路径:
abfs://storage@127.0.0.1:10000/devstoreaccount1/selim/test.csv
如果通过上述正则表达式解析,这将是 output,导致对 Azurite 服务器的 api 调用不正确:
是否有可能有一个可以处理两个 URI 或 2 个正则表达式的 1 个正则表达式来解决这个问题
解决方案 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://storage@myaccount.dfs.core.windows.net/selim/test.csv",
"abfs://storage@127.0.0.1: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-----");
}
}
}
}
}
Output:
abfs://storage@myaccount.dfs.core.windows.net/selim/test.csv:
fileSystem: storage
accountName: myaccount
accountSuffix: '.dfs.core.windows.net'
relativePath:selim/test.csv
-----
abfs://storage@127.0.0.1:10000/devstoreaccount1/selim/test.csv:
fileSystem: storage
accountName: devstoreaccount1
accountSuffix: ''
relativePath:selim/test.csv
方案二
您可以使用两个不同的正则表达式,如果第一个没有找到匹配项,将尝试第二个。 第一个:
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://storage@myaccount.dfs.core.windows.net/selim/test.csv",
"abfs://storage@127.0.0.1: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;
}
}
Output:
'fileSystem': 'storage'
'accountSuffix': '.dfs.core.windows.net'
'accountName': 'myaccount'
'relativePath': 'selim/test.csv'
----------------
'fileSystem': 'storage'
'accountSuffix': ''
'accountName': 'devstoreaccount1'
'relativePath': 'selim/test.csv'
----------------
No match!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.