Zac*_*ach 3 powershell substring
$a会是“角落”或“特殊角”之类的东西,但可能会长到“标准窗户最多可打开37个”之类的东西,这意味着Substring()如果我无法使用简单的方法(无论如何,我都知道)想要查找中的前20个字符$a(这就是问题)。
我发现这是专为我想要的东西而设计的,但是它给了我
“ char [] ToCharArray(),char [] ToCharArray(int startIndex,int length)”
而且我不知道如何使其正常运行。
($a.ToCharArray | select -First 20) -join ""
Run Code Online (Sandbox Code Playgroud)
Lee_Dailey 的有用答案很好地解释了您尝试的问题,并提供了一个可行的解决方案,包括使用一元形式的解决方案-join。
只是为了向未来的读者阐明为什么使用 just.Substring()不是实现最多N 个字符提取的选项。逻辑:尝试提取超出输入字符串长度的子字符串会导致异常:
# OK: -> 'ab'
'abc'.Substring(0, 2)
# !! Exception, because at most 3 chars. can be extracted
# !! "[...]: Index and length must refer to a location within the string. [...]"
'abc'.Substring(0, 4)
Run Code Online (Sandbox Code Playgroud)
不过,您使用管道解决该问题的Select-Object方法有点粗暴。
以下是使用表达式的性能更好的替代方案。
Esperento 的有用答案提供了性能最佳的解决方案,仅使用 .NET 功能,尽管它有点“嘈杂”,因为它需要嵌套方法调用和变量(而不是文字)作为输入,因为必须引用该变量在嵌套方法调用中。
下面的方法更符合 PowerShell 习惯。
LotPings在评论中提供了一个简洁的解决方案,基于字符串可以隐式地视为字符数组,因此可以应用数组切片;请注意,索引是0基于 - 的:
# -> 'ab'
-join 'abc'[0..1]
# -> 'abc'
# Always-safe equivalent of:
# 'abc'.Substring(0, 4)
-join 'abc'[0..3]
Run Code Online (Sandbox Code Playgroud)
Range 表达式的0..3计算结果为 array 0, 1, 2, 3,导致指定索引处的字符作为字符数组返回,-join然后重新组装成字符串。
默认情况下,PowerShell会忽略数组边界之外的索引,但
需要注意的是,如果Set-StrictMode -Version 3或更高版本有效,则上述情况也会导致错误。
一个性能更好且不敏感的替代方案Set-StrictMode是将运算符与 regex (正则表达式)一起使用-replace。
也就是说,这个解决方案有些晦涩难懂。
# -> 'ab'
# Equivalent of:
# 'abc'.Substring(0, 2)
'abc' -replace '(?<=.{2}).+'
# -> 'abc'
# Always-safe equivalent of:
# 'abc'.Substring(0, 4)
'abc' -replace '(?<=.{4}).+'
Run Code Online (Sandbox Code Playgroud)
.{4}完全匹配字符串开头的4字符 ( ) (隐式),而不在匹配中包含这些字符( ,后向断言);然后匹配所有剩余的字符(一个或多个)。.(?<=...).+
最终效果是,所有超过 4 个字符的输入字符串都将从第 5 个字符开始的所有内容替换为空字符串(由于缺少替换操作数),实际上只留下前 4 个字符。
包含4 个或更少字符的输入字符串按原样传递(无需提取)。
对于多行输入字符串,需要做更多的工作(内联选项也(?s)可以.匹配换行符(`n)):
# Extracts the first 3 chars, the equivalent of: "a`nb"
"a`nbc" -replace '(?s)(?<=.{3}).+'
Run Code Online (Sandbox Code Playgroud)
还可以考虑使用一个简单的辅助函数:
function substr ([string] $String, [int] $Start = 0, [int] $Length = -1) {
if ($Length -lt -1 -or $Start -lt 0) { # Quietly output '' for invalid arguments.
''
} elseif ($Length -eq -1 -or $Start + $Length -ge $String.Length) {
$String.Substring($Start)
} else {
$String.Substring($Start, $Length)
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,您需要使用参数模式语法(类似 shell、空格分隔的参数)来调用它,就像 PowerShell 中的任何函数一样:
# -> 'ab'
# Same as:
# substr abc 0 2
# substr -String abc -Start 0 -Length 2
substr 'abc' -Length 2
# -> 'abc'
substr 'abc' -Length 4
Run Code Online (Sandbox Code Playgroud)
字符串没有.ToCharArray 属性。您所使用的将为您带来该方法的重载。[ 咧嘴笑 ]尝试输入带引号的字符串,添加一个点,然后查看所有显示的内容。
你想要的是.ToCharAray() 方法。
因此,将那些缺少的括号添加到调用中,它将起作用。[ 咧嘴 ]
同样,-join在这种情况下,您真的应该使用字符串运算符的“前端”版本。“背后”版本用于添加定界符。看看差异[都给出相同的结果] ...
-join ('Standard Window Openings up to 37'.ToCharArray() | Select-Object -First 20) ('Standard Window Openings up to 37'.ToCharArray() | Select-Object -First 20) -join '' 第一个示例更适合您的实际目标。