从字符串中提取字符串,选择方法



我有一个字符串,如下所示:[错误]无法处理站点:https://xxxxxxxxx/teams/xxxxxx。远程服务器返回错误:(404)找不到。

挑战在于提取这个字符串中突出显示的部分。

尝试了一些拆分操作,但没有成功。

使用-match运算符对URL执行正则表达式搜索,然后提取匹配的字符串值:

# define input string
$errorString = '[Error] Failed to process site: https://some.domain.tld/teams/xxxxxx. The remote server returned an error: (404) Not Found.'
# define regex pattern for a URL followed by a literal dot
$urlFollowedByDotPattern = 'https?://(?:www.)?[-a-zA-Z0-9@:%._+~#=]{1,256}.[a-zA-Z0-9()]{1,6}b(?:[-a-zA-Z0-9()@:%_+.~#?&//=]*)(?=.)'
# perform match comparison
if($errorString -match $urlFollowedByDotPattern){
# extract the substring containing the URL matched by the pattern
$URL = $Matches[0]
# remove everything before the last slash
$pathSuffix = $URL -replace '^.*/'
}

如果找到了URL,则$pathSuffix变量现在包含后面的xxxxxx部分

使用基于正则表达式的
-replace运算符为Mathias R.Jessen的有用答案提供一个简洁的替代方案:

-replace可以通过进行子字符串提取

  • 制定与整个输入字符串匹配的正则表达式
  • 使用该正则表达式内的捕获组((...))来捕获感兴趣的子字符串,并将其用作替换字符串;例如替换字符串中的$1是指第一捕获组捕获了什么
$str = '[Error] Failed to process site: https://xxxxxxxxx/teams/xxxxxx. The remote server returned an error: (404) Not Found.'
$str -replace '.+https://.+/([^/]+)..+', '$1' # -> 'xxxxxx'

有关regex的解释以及尝试使用它的选项,请参阅此regex101.com页面。

注:

  • 如果正则表达式不匹配,则整个输入字符串将按原样返回。

  • 在这种情况下,如果您希望返回空字符串,请使用zett42建议的技术:将|.*附加到正则表达式,或者(|),如果原始正则表达式不匹配,则无条件地将整个输入字符串与.*匹配,在这种情况下,由于没有使用捕获组,$1计算为空字符串作为有效返回值:

    # Note the addition of |.*
    'this has no URL' -replace '.+https://.+/([^/]+)..+|.*', '$1' # -> ''
    
    • regex101.com页面

如果这样的正则表达式太令人费解,您可以尝试一种结合-split-like的多步骤方法

$str = '[Error] Failed to process site: https://xxxxxxxxx/teams/xxxxxx. The remote server returned an error: (404) Not Found.'
# -> 'xxxxxx'
# Note the line continuations (` at the very end of the lines)
# required to spread the command across multiple lines for readability.
(
-split $str        <#  split into tokens by whitespace #> `
-like 'https://*'  <# select the token that starts with 'https://' #> `
-split '/'         <# split it into URL components by '/' #>
)[-1]?.TrimEnd('.')  <# select the last component and trim the traiing "." #>

注:

  • 如果未找到感兴趣的令牌(返回$null),则使用条件成员访问运算符?.可以防止语句终止错误,但它需要PowerShell(Core)7.1+

  • 在早期版本中,也可以用-replace '.$'替换?.TrimEnd('.'),默认为空字符串