regex 正则表达式字符串替换在PowerShell中过早结束

dbf7pr2w  于 2023-06-07  发布在  Shell
关注(0)|答案(1)|浏览(140)

我正在使用PowerShell(5.1),并试图在将其传递到URL之前对字符串进行编码。API使用某些字符(例如冒号(:)表示“等于”),用于属性和其值之间。如果值部分出现冒号(例如),则应使用URL安全编码(%3A)替换。
以下PowerShell在字符串为filter=username:"user1@domain.com"时工作。符号@替换为%40。但是,如果字符串是filter=username:"user1@domain.com"|"user2@domain.com",则仅替换第一个@
PowerShell代码段看起来像这样:

$Filter = 'filter=username:"user1@domain.com"'
$pattern1 = '[^a-zA-Z\d\s]' # Match any non-alpha numeric or white space character.
$pattern2 = '(?:>:|<:|:|>|<|!:|:|~|!~|@)(?:")(.*?)(?:")' # Allow us to replace characters in the filter. We will leave some of the characters alone, since they are used by the API in certain spots. For example, ":" means equal between the property name and value but should be replaced in the value portion of the pair.
$regex = [Regex]::new($pattern2)
$regex.Matches($Filter) | ForEach-Object {
    $Filter = $Filter -replace ([regex]::Escape($_.Groups[1].value)), ([uri]::EscapeDataString($_.Groups[1].value))
}

我错过了什么?

cnwbcb6i

cnwbcb6i1#

我不清楚确切的要求,但也许下面的内容可以满足您的需求:

# Sample string to transform.
$filter = 'filter=username:"user1@domain.com"|"user2@domain.com"' 

[regex]::Replace(
  $filter,
  '(?<=[:|><~@]").*?(?=")',
  {
    param($m)
    [Uri]::EscapeDataString($m.Value)
  }
)

这依赖于所有属性值都包含在"..."中(并且没有转义的 embedded"),并且前面有以下任何一个字符:: | < > ~ @
结果(只有"..."子字符串中的属性值是URI转义的):

filter=username:"user1%40domain.com"|"user2%40domain.com"

有关正则表达式的解释和使用它的能力,请参见this regex101.com page
至于你尝试了什么
正则表达式中唯一缺少的是\|段,以便在属性值的开头"(插入在|@之前)之前也匹配逐字|

(?:>:|<:|:|>|<|!:|:|~|!~|\||@)(?:")(.*?)(?:")

参见this regex101.com page
但是,请注意,可以通过使用字符集([...])并删除冗余部分来简化正则表达式:

(?:[:|><~@](?:")(.*?)(?:")

这种简化的形式在上面的解决方案中使用,尽管通过使用 *lookaroundAssert *,使得不需要捕获组。

相关问题