我需要在nodejs中解析Azure Blob URI并提取存储帐户名,容器名和blob名。
我调查了azure-sdk-for-node和azure-storage-node但我找不到这样做的方法。
如果Blob URI无效,我也想检测一下,所以可能正则表达式(如果可能的话)是一个很好的方法。
Blob URI的一些示例:
https://myaccount.blob.core.windows.net/mycontainer/myblob
http://myaccount.blob.core.windows.net/myblob
https://myaccount.blob.core.windows.net/$root/myblob
答案 0 :(得分:0)
通过关注specification from Azure,我想出了以下函数(gist),它使用正则表达式来解析blob uri,如果blob uri无效,它也会抛出错误。
存储帐户名称和容器名称应该完全正确/精确,只有blob名称我有点松散,因为定义起来比较复杂。
/**
* Validates and parses given blob uri and returns storage account,
* container and blob names.
* @param {string} blobUri - Valid Azure storage blob uri.
* @returns {Object} With following properties:
* - {string} storageAccountName
* - {string} containerName
* - {string} blobName
* @throws {Error} If blobUri is not valid blob uri.
*/
const parseAzureBlobUri = (blobUri) => {
const ERROR_MSG_GENERIC = 'Invalid blob uri.'
const storageAccountRegex = new RegExp('[a-z0-9]{3,24}')
const containerRegex = new RegExp('[a-z0-9](?!.*--)[a-z0-9-]{1,61}[a-z0-9]')
const blobRegex = new RegExp('.{1,1024}') // TODO: Consider making this one more precise.
const blobUriRegex = new RegExp(
`^http[s]?:\/\/(${ storageAccountRegex.source })\.blob.core.windows.net\/`
+ `(?:(\$root|(?:${ containerRegex.source }))\/)?(${ blobRegex.source })$`
)
const match = blobUriRegex.exec(blobUri)
if (!match) throw Error(ERROR_MSG_GENERIC)
return {
storageAccountName: match[1],
// If not specified, then it is implicitly root container with name $root.
containerName: match[2] || '$root',
blobName: match[3]
}
}
答案 1 :(得分:0)
您可以使用url.parse
。
我的主要原因是避免使用正则表达式,它也更容易理解,阅读和修改。
以下是示例代码:
const url = require('url')
const parseAzureBlobUri = (blobUrl) => {
let uri = url.parse(blobUrl)
// Extract the storage account name
let storageAccountName = uri.hostname.split('.')[0]
// Remove the 1st trailing slash then extract segments
let segments = uri.pathname.substring(1).split('/')
// If only one segment, this is the blob name
if(segments.length === 1){
return {
storageAccountName,
containerName: '$root',
blobName: segments[0]
}
}
// get the container name
let containerName = segments[0]
// Remove the containername from the segments
segments.shift()
return {
storageAccountName,
containerName,
blobName: segments.join('/')
}
}