Powershell:如何获取文本的子字符串

Powershell: How to grab substring of text

我有一个字段,description,其中包含可预测格式的文本,看起来像这 2 个选项中的任何一个,

DEACTIVATED on Tue Apr 02 2019

DEACTIVATED on Tue Apr 02 2019 | MANAGER John Smith

我需要在每种情况下只获取日期,Tue Apr 02 2019,同时考虑日期之后是否有文本。

示例用例

$string = "DEACTIVATED on Tue Apr 02 2019 | MANAGER John Smith"
$date   = "Tue Apr 02 2019"

不确定我是否理解正确,但子字符串是这样工作的:

$string = "DEACTIVATED on Tue Apr 02 2019 | MANAGER John Smith"
#.substring(starting point, how many)
$date = $string.Substring(15,10)
$date
Tue Apr 02

这是我得到它的方式,因为我必须考虑对象之间的一些潜在差异

$text = "DEACTIVATED on Tue Apr 02 2019 | MANAGER John Smith"
$start_pos = $text.IndexOf('on')

$substring = $text.substring($start_pos + 3)

if ($text.IndexOf(' | ') -gt -1) {
    $end_pos = $text.indexOf(' | ')
    $substring = $substring.substring(0, $end_pos)
}

这里有一个稍微不同的方法来完成这项工作。 [咧嘴一笑]

它的作用...

  • 前 4 行创建了一个字符串数组以用于
  • 遍历集合
  • 在“|”上拆分
  • 取结果数组中的第一项
  • 删除所有 leading/trailing 空格
  • 使用命名捕获组获取 DEACTIVATED on
  • 之后的日期字符串
  • 显示生成的命名捕获组
  • 将其转换为 [datetime] 对象并显示

这是代码...

$DescriptionText = @(
    'DEACTIVATED on Sat May 11 2019'
    'DEACTIVATED on Tue Apr 02 2019 | MANAGER John Smith'
    )

foreach ($DT_Item in $DescriptionText)
    {
    $Null = $DT_Item.Split('|')[0].Trim() -match 'DEACTIVATED on (?<DeactivationDate>.+)'

    $Matches.DeactivationDate
    [datetime]::ParseExact($Matches.DeactivationDate, 'ddd MMM dd yyyy', $Null)
    '=' * 20
    }

输出...

Sat May 11 2019

2019 May 11, Saturday 12:00:00 AM
====================
Tue Apr 02 2019
2019 April 02, Tuesday 12:00:00 AM
====================

我想不通第一对输出中的空白行是从哪里来的。 [脸红]

我会使用:


## Q:\Test19\SO_56060672.ps1

$strings = @"
DEACTIVATED on Tue Apr 02 2019

DEACTIVATED on Tue Apr 09 2019 | MANAGER John Smith
"@ -split '\r?\n'

$RE = '(?<=DEACTIVATED on ).*\d{4}'

## Output found datetime strings
$strings | Select-String $RE | ForEach-Object{$_.Matches.value}

## if your locale is English convert to [datetime] type
$strings | Select-String $RE | ForEach-Object{
    [datetime]::ParseExact($_.Matches.value,'ddd MMM dd yyyy',$null)
}

## if your locale is NOT English convert to [datetime] type
$strings | Select-String $RE | ForEach-Object{
    [datetime]::ParseExact($_.Matches.value,'ddd MMM dd yyyy',
       [System.Globalization.CultureInfo]::InvariantCulture)
}

我的德语语言环境中第一个和最后一个的输出:

Tue Apr 02 2019
Tue Apr 09 2019

Dienstag, 2. April 2019 00:00:00
Dienstag, 9. April 2019 00:00:00