【问题标题】:How to find the positions of all instances of a string in a specific line of a txt file?如何在txt文件的特定行中查找字符串的所有实例的位置?
【发布时间】:2020-05-20 16:32:10
【问题描述】:

假设我有一个包含多个日期/时间行的 .txt 文件:

2020 年 5 月 5 日上午 5:45:45

2020 年 5 月 10 日下午 12:30:03

我想在一行中找到所有斜线的位置,然后转到下一行。

所以对于第一行,我希望它返回值:

1 3

对于第二行,我想要:

1 4

我该怎么做呢?

我目前有:

$firstslashpos = Get-Content .\Documents\LoggedDates.txt | ForEach-Object{
     $_.IndexOf("/")}

但这只会给我每行的第一个“/”,并同时给我所有行的结果。我需要它循环,我可以找出每行的每个“/”之间的空间。

对不起,如果我措辞不好。

【问题讨论】:

  • “我需要它来循环,我可以找出每行的每个“/”之间的空间。” - 就是这样。 ForEach-Object 正在循环LoggedDates.txt 的行。您需要在 ForEach-Object 内再循环一次以遍历每一行的字符 ($_)。

标签: powershell substring


【解决方案1】:

您确实可以为此使用String.IndexOf() 方法!

function Find-SubstringIndex
{
  param(
    [string]$InputString,
    [string]$Substring
  )

  $indices = @()

  # start at position zero
  $offset = 0

  # Keep calling IndexOf() to find the next occurrence of the substring
  # stop when IndexOf() returns -1
  while(($i = $InputString.IndexOf($Substring, $offset)) -ne -1){
    # Keep track of the index at which the substring was found
    $indices += $i
    # Update the offset, we'll want to start searching for the next index _after_ this one
    $offset = $i + $Substring.Length
  }
}

现在你可以这样做了:

Get-Content listOfDates.txt |ForEach-Object {
  $indices = Find-SubstringIndex -InputString $_ -Substring '/'
  Write-Host "Found slash at indices: $($indices -join ',')"
}

【讨论】:

  • 目前我收到关于while(($i - $string.InexOf($substring, $offset)) -ne -1)... 部分为空值的错误。我怀疑这可能是因为在我的文件中,顶部有五行左右不会包含“/”?我该如何解决?
  • @justmayo 你有- 而不是=InexOf 而不是IndexOf
  • 对不起,我认为这只是我评论中的一个错字。我在另一台机器上编写代码,所以没有复制粘贴
  • 我明白了。我认为问题在于函数参数被命名为$InputString,但是被搜索的变量被命名为$string
  • 是的,这是一个错字,现在已修复
【解决方案2】:

一个简洁的解决方案是使用[regex]::Matches(),它在给定字符串中查找给定regular expression 的所有匹配项,并返回匹配对象的集合,这些对象还指示每个匹配项的索引(字符位置):

# Create a sample file.
@'
5/5/2020 5:45:45 AM
5/10/2020 12:30:03 PM
'@ > sample.txt

Get-Content sample.txt | ForEach-Object {

  # Get the indices of all '/' instances.
  $indices = [regex]::Matches($_, '/').Index

  # Output them as a list (string), separated with spaces.
  "$indices"

}

以上产出:

1 3
1 4

注意:

  • 不包含/ 实例的输入行将导致空行。

  • 如果您希望将索引输出为 数组(集合)而不是 字符串,请使用
    , [regex]::Matches($_, '/').Index 作为ForEach-Object 脚本块; , 的一元形式,array constructor operator 确保(通过瞬态辅助数组)方法调用返回的集合作为一个整体输出。如果省略,则索引会一一输出,收集在变量中时会生成一个平面数组。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-28
    • 1970-01-01
    • 2012-08-17
    • 2014-04-23
    • 2021-02-07
    • 2022-01-24
    相关资源
    最近更新 更多