gpt4 book ai didi

java - 用于解析 Azure Data Lake Storage Gen2 URI 的正则表达式,以便使用 Azurite 进行生产和测试

转载 作者:行者123 更新时间:2023-12-05 05:46:04 25 4
gpt4 key购买 nike

在我的 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://<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="9be8eff4e9fafcfedbf6e2faf8f8f4eef5efb5fffde8b5f8f4e9feb5ecf2f5fff4ece8b5f5feef" rel="noreferrer noopener nofollow">[email protected]</a>/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 documentation 中的建议针对实际的 Azure 服务器运行单元测试。 .

Azurite 使用与 Azure 不同的文件 URI,因此这使得我的上述正则表达式对于测试目的无效。 Azurite 文件 URI 采用以下格式:

abfs[s]://<file_system>@<local_ip>:<local_port>/<account_name>/<path>/<file_name>

Azurite 默认 account_namedevstoreaccount1,因此这里是 Azurite 上文件的示例路径:

abfs://<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="86f5f2e9f4e7e1e3c6b7b4b1a8b6a8b6a8b7" rel="noreferrer noopener nofollow">[email protected]</a>:10000/devstoreaccount1/selim/test.csv

如果由上述正则表达式解析,这将是输出,导致对 Azurite 服务器的错误 api 调用:

  • 文件系统:存储(正确)
  • accountName:127(不正确,应为:devstoreaccount1)
  • accountSuffix:.0.0.1:10000(不正确,应为空字符串)
  • 相对路径:devstoreaccount1/selim/test.csv(不正确,应为 selim/test.csv)

是否可以使用 1 个正则表达式来处理两个 URI 或 2 个正则表达式来解决此问题

最佳答案

解决方案1

您可以为此使用单一模式,但您需要检查代码中匹配的组以确定在何处捕获必要的详细信息。

正则表达式看起来像

abfss?://(?:([^@/]*)@(\d{1,3}(?:\.\d{1,3}){3}:\d+)/([^/]+)|([^/]+)@([^.]+)(\.[^/]+))(?:/(.+))?

请参阅 regex demo([^@/]*)@(\d{1,3}(?:\.\d{1,3}){3}:\d+)/([^/]+) 替代方案允许捕获文件系统、@ 后的 IP 地址等部分(带有端口号)以及斜杠后的帐户名。

Java code 看起来像

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://<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="d3a0a7bca1b2b4b693beaab2b0b0bca6bda7fdb7b5a0fdb0bca1b6fda4babdb7bca4a0fdbdb6a7" rel="noreferrer noopener nofollow">[email protected]</a>/selim/test.csv",
"abfs://<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="384b4c574a595f5d78090a0f160816081609" rel="noreferrer noopener nofollow">[email protected]</a>: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://<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="added9c2dfcccac8edc0d4cccecec2d8c3d983c9cbde83cec2dfc883dac4c3c9c2dade83c3c8d9" rel="noreferrer noopener nofollow">[email protected]</a>/selim/test.csv:
fileSystem: storage
accountName: myaccount
accountSuffix: '.dfs.core.windows.net'
relativePath:selim/test.csv
-----
abfs://<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="dcafa8b3aebdbbb99cedeeebf2ecf2ecf2ed" rel="noreferrer noopener nofollow">[email protected]</a>:10000/devstoreaccount1/selim/test.csv:
fileSystem: storage
accountName: devstoreaccount1
accountSuffix: ''
relativePath:selim/test.csv

解决方案2

您可以使用两个不同的正则表达式,如果第一个没有找到匹配项,则将尝试第二个。第一个:

abfss?://([^@/]*)@(\d{1,3}(?:\.\d{1,3}){3}:\d+)/([^/]+)(?:/(.+))?

参见 this regex demo 。第二个:

abfss?://([^/]+)@([^.]+)(\.[^/]+)(?:/(.+))?

参见 this regex demo 。由于该 URL 也匹配第一种类型的 URL,因此您需要确保按固定顺序运行它们。

参见 Java demo:

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://<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="0576716a7764626045687c6466666a706b712b6163762b666a77602b726c6b616a72762b6b6071" rel="noreferrer noopener nofollow">[email protected]</a>/selim/test.csv",
"abfs://<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="275453485546404267161510091709170916" rel="noreferrer noopener nofollow">[email protected]</a>: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!

关于java - 用于解析 Azure Data Lake Storage Gen2 URI 的正则表达式,以便使用 Azurite 进行生产和测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71233702/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com