如何保存在数组中的某些字符的所有位置在一个字符串?



我有一个包含多个斜杠的字符串,例如:$message = ab/cde/f/ghijklm/no/p

我想有一个函数,当在这个$message上运行时,将返回一个$slash_array,其中包含所有斜杠的位置值。

。,在上面的例子中,我将输入:

PS > Write-Output $slash_array
3,7,9,17,20

然后我想使用这些值在每个字符之后插入一个斜杠,除非它在这些位置之一(我不希望程序在已经存在的斜杠之后添加一个斜杠)。

============================= 编辑 ============================

首先,一个小旁注:你可能会觉得我不礼貌,但是@phcluv删除了所有的介绍性句子(这在stackoverflow中正常吗?这里很新…)

我试图简化这个问题,但实际上:

$message = "my name is silloky"

我希望每个字符之间有一个斜杠(/),两个单词之间有一个双斜杠(//),所以我的消息看起来像这样:m/y//n/a/m/e//i/s//s/i/l/l/o/k/y(或者在最后有一个斜杠,我真的不在乎)。

所以我有了用1个斜杠替换原始消息中的空格的想法,然后在每个字符之后插入斜杠(所以如果那里已经有一个斜杠,那就会有2个斜杠),除非它是斜杠(我们会有replace的斜杠,insert的斜杠在它之前的字符之后,insert在斜杠之后,这是一个字符,这将使3个斜杠)。我认为PS将无法判断当前字符是否是/,所以我认为我最好使用insert会忽略的位置数组。所以当我叫你进来的时候…

我有几个灵感来自你们所有人的想法…如果我自己发布答案并接受它可以吗?或者我应该发布一个明确的答案,但接受最有帮助的答案?

循环遍历字符并检查,然后返回索引

PS C:> $message = "ab/cde/f/ghijklm/no/p"
PS C:> $slash_array = for ($i = 0; $i -lt $message.Length; $i++)
{ if ($message[$i] -eq '/') { $i + 1 } }
PS C:> $slash_array
3
7
9
17
20
PS C:> $slash_array -join ', '
3, 7, 9, 17, 20
PS C:>

但是如果你只是想在任何非斜杠字符之后插入一个斜杠,为什么不只是做一个正则匹配然后替换?

PS C:> $message -replace '([^/])(?!/)', '$1/'
a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/

([^/])(?!/)匹配后面没有斜杠的非斜杠字符,然后在匹配的字符

后面添加斜杠其他选择:

PS C:> ($message.ToCharArray() | Where-Object { $_ -ne '/' }) -join '/'
a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p
PS C:> $message.Replace("/", "").ToCharArray() -join '/'
a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p

正如Theo指出的那样,由于您的意图是将除斜杠(/)以外的所有单个字符与/分开,因此您不需要找到现有斜杠的索引,因为该方法可以简化为:

  • 删除现有的/实例,使用-replace操作符

  • 将结果中的单个字符与-join操作符

    连接起来
    • 单个字符数组是通过下面的.ToCharArray().NET string方法获得的;或者,您可以强制转换为[char[]]
# -> 'a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p'
('ab/cde/f/ghijklm/no/p' -replace '/').ToCharArray() -join '/'

使用(...) + '/'也可以在最后一个字符之后放置/。或者,考虑phuclv基于正则表达式的解决方案。


正如zett42所指出的,获得基于0的字符或子字符串位置的最直接的方法,是使用[regex]::Matches().NET方法:

# -> 2, 6, 8, 16, 19
[regex]::Matches('ab/cde/f/ghijklm/no/p', '/').Index

注意,尽管方法调用返回多个(一个集合)匹配信息对象,但是.Index可以用来从每个中提取索引(位置)值,这得益于PowerShell方便的成员访问枚举特性

好的,这里有三种可能:

第一种可能

非常简单(我发现这是错误的,我甚至不明白它是如何工作的,但无论如何),实际上不需要/的数组!不好意思😭

$message = "my name is silloky"
[int] $length = $message.Length
[int] $times = 0
[int] $char_num = 1
do{
$message = $message.Insert($char_num,'/')
$char_num = $char_num + 2
$times = $times + 1
}until($times -eq $length)
$message = $message.replace(' ','')
Write-Output "The slashed output of the message is : $message

第二个可能性使用@phuclv的极其简单的代码,让我觉得自己像一个彻头彻尾的复杂的人!…

([^/])(?!/)实际上取代了上面的do-until循环,但它仍然留下了一些空格!

$message = "my name is silloky"
$message $message -replace '([^/])(?!/)', '$1/'
$message = $message.replace(' ','')
Write-Output $message

第三种可能

去他的吧,太复杂了…😁

结论

顺便说一句,我已经测试了我在这里提供的代码,但我不能保证…

我想我会选择第一种可能性,因为我应该自己做这些代码,我真的不在乎我的代码是否长了10行(这会让非编码人员看起来更酷…)。

但是感谢@phuclv, @mkelement0, @zett42(即使你没有参与这个对话,你间接地帮助了我)和@Theo无论如何都帮助了我。

无论你是谁阅读这篇文章,如果你遇到一个(或者如果我的一个代码片段不工作),请在评论中随意提出另一种可能性!🧠💡

最新更新