需要将时间与字符串分开

时间:2019-05-23 16:43:05

标签: powershell

我正在寻找一种方法,根据用户输入的内容,在看起来像是上午8点或上午8:00之前删除所有文本。这可能是包括pm在内的任何时间。

这是我要找的东西:

$appointment = "9th annual fundraiser - 8:30 am - 3 pm"

它也可能像这样:

$appointment = "9th annual fundraiser - (8:30 am - 3 pm)"

$appointment = "9th annual fundraiser - (event 8:30 am - 3 pm)"

$appointment = "9th annual fundraiser 8:30 am - 3:00 pm"

我在大多数其他应用程序中使用的是以下内容:

$appointment -creplace '^[^1-9]*' 

,但是在这种情况下不起作用,我一直在使用?和其他所有内容寻找良好的答案,但我不理解。

我的目标是使它跳过这种情况下的第一个数字(可以是1st,2nd,3rd,4th等),并使其超时。这样$appointment看起来像:

上午8:30-下午3点

我尝试使用这些公式,但似乎无法告诉它拉出 通常 的时间是X:XX。

2 个答案:

答案 0 :(得分:1)

以下是基于此正则表达式的解决方案:\d+(:\d+)?\s+[ap]m

RegEx说明:

  1. \d+:一位或多位数字
  2. (:\d+)?:冒号后跟一个或多个 数字。此组合的一或零。这是如何工作的3:00 上午和凌晨3点。
  3. \s+:一个或多个空格(在3:00和AM之间)。使其\s*成为可选的空间。
  4. [ap]m:上午或下午

解决方案1 ​​

$regex = "\d+(:\d+)?\s+[ap]m"
$matches = ($appointment | Select-String $regex -AllMatches).Matches.Value
$matches -join " - "

解决方案2

$regex = "\d+(:\d+)?\s+[ap]m"
$regex = $regex + "\s*[-]\s*" + $regex
$matches = ($appointment | Select-String $regex -AllMatches).Matches.Value
$matches

如果您确定输入内容包含2次,则我更喜欢解决方案1,因为它与两次之间的时间无关。因此,它也适用于“下午3点至下午6点”之类的事情。

答案 1 :(得分:0)

这是使用正则表达式的一种方法:

Function Get-StringTime()
{
    # Set up a results ArrayList
    $results = New-Object System.Collections.ArrayList

    $regexs = @(
        # See https://regexr.com/ and you can drop
        # these expressions into the bar up top and
        # the Tools section at the bottom will explain
        # each expression

        [regex]"\b\d{1}:\d{2}(am|pm)-\d{1}:\d{2}(am|pm)\b", # matches 8:00am-3:00pm
        [regex]"\b\d{1}(am|pm)-\d{1}(am|pm)\b",       # matches 8am-3pm
        [regex]"\b\d{1}:\d{2}(am|pm)-\d{1}(am|pm)\b", # matches 8:00am-3pm
        [regex]"\b\d{1}(am|pm)-\d{1}:\d{2}(am|pm)\b"  # matches 8am-3:00pm
    )

    # Setup sample data, 1 for each match
    $a1 = '9th annual fundraiser - (8am - 3pm)'
    $a2 = '9th annual fundraiser - (8am - 3:00pm)'
    $a3 = '9th annual fundraiser - (8:00am - 3pm)'
    $a4 = '9th annual fundraiser - (8:00am - 3:00pm)'
    $a5 = '9th annual fundraiser - (13:00pm - 1:00am)'
    $arrs = @($a1, $a2, $a3, $a4, $a5)

    foreach($appointment in $arrs)
    {
        # strip out all the spaces so we can use less regexs

        $newAppointment = $appointment.Replace(' ','')

        Write-Host "`nAppointment data: " -NoNewline
        Write-Host $newAppointment -ForegroundColor Magenta

        # check this against each regex

        foreach($regex in $regexs)
        {
            Write-Host "Trying regex: " -NoNewline
            <#
                To show the user the regex being used
                we need to convert to a string, otherwise
                it will return an object type of RegEx
                which default outputs like this:

                Options MatchTimeout      RightToLeft
                ------- ------------      -----------
                   None -00:00:00.0010000       False
            #>

            Write-Host $($regex.ToString()) -ForegroundColor Yellow

            if($regex.Match($newAppointment).Value -ne '')
            {
                Write-Host "Match found | " -NoNewline  -ForegroundColor Green
                Write-Host "Item: $($arrs.IndexOf($appointment)) | Regex match Index: $($regexs.IndexOf($regex))"

                $results.Add([PSCustomObject]@{
                                                TimeString=$regex.Match($newAppointment).Value;
                                                AppointmentIndex=$($arrs.IndexOf($appointment));
                                                MatchingRegex=$regex.ToString();
                                                MatchingRegexIndex=$regexs.IndexOf($regex);
                }) | Out-Null
            }
            else { 
                Out-Null 
            }
        }
    }

    return $results
}

Get-StringTime

输出返回(在PS控制台中带有颜色):

Appointment data: 9thannualfundraiser-(8am-3pm)
Trying regex: \b\d{1}:\d{2}(am|pm)-\d{1}:\d{2}(am|pm)\b
Trying regex: \b\d{1}(am|pm)-\d{1}(am|pm)\b
Match found | Item: 0 | Regex match Index: 1
Trying regex: \b\d{1}:\d{2}(am|pm)-\d{1}(am|pm)\b
Trying regex: \b\d{1}(am|pm)-\d{1}:\d{2}(am|pm)\b

Appointment data: 9thannualfundraiser-(8am-3:00pm)
Trying regex: \b\d{1}:\d{2}(am|pm)-\d{1}:\d{2}(am|pm)\b
Trying regex: \b\d{1}(am|pm)-\d{1}(am|pm)\b
Trying regex: \b\d{1}:\d{2}(am|pm)-\d{1}(am|pm)\b
Trying regex: \b\d{1}(am|pm)-\d{1}:\d{2}(am|pm)\b
Match found | Item: 1 | Regex match Index: 3

Appointment data: 9thannualfundraiser-(8:00am-3pm)
Trying regex: \b\d{1}:\d{2}(am|pm)-\d{1}:\d{2}(am|pm)\b
Trying regex: \b\d{1}(am|pm)-\d{1}(am|pm)\b
Trying regex: \b\d{1}:\d{2}(am|pm)-\d{1}(am|pm)\b
Match found | Item: 2 | Regex match Index: 2
Trying regex: \b\d{1}(am|pm)-\d{1}:\d{2}(am|pm)\b

Appointment data: 9thannualfundraiser-(8:00am-3:00pm)
Trying regex: \b\d{1}:\d{2}(am|pm)-\d{1}:\d{2}(am|pm)\b
Match found | Item: 3 | Regex match Index: 0
Trying regex: \b\d{1}(am|pm)-\d{1}(am|pm)\b
Trying regex: \b\d{1}:\d{2}(am|pm)-\d{1}(am|pm)\b
Trying regex: \b\d{1}(am|pm)-\d{1}:\d{2}(am|pm)\b

Appointment data: 9thannualfundraiser-(13:00pm-1:00am)
Trying regex: \b\d{1}:\d{2}(am|pm)-\d{1}:\d{2}(am|pm)\b
Trying regex: \b\d{1}(am|pm)-\d{1}(am|pm)\b
Trying regex: \b\d{1}:\d{2}(am|pm)-\d{1}(am|pm)\b
Trying regex: \b\d{1}(am|pm)-\d{1}:\d{2}(am|pm)\b

TimeString    AppointmentIndex MatchingRegex                             MatchingRegexIndex
----------    ---------------- -------------                             ------------------
8am-3pm                      0 \b\d{1}(am|pm)-\d{1}(am|pm)\b                              1
8am-3:00pm                   1 \b\d{1}(am|pm)-\d{1}:\d{2}(am|pm)\b                        3
8:00am-3pm                   2 \b\d{1}:\d{2}(am|pm)-\d{1}(am|pm)\b                        2
8:00am-3:00pm                3 \b\d{1}:\d{2}(am|pm)-\d{1}:\d{2}(am|pm)\b                  0

希望这会给您一些破解的机会。如果您想使其更可重用,则可以在函数调用中添加一个参数,例如:

Function Get-StringTime([String]$AppointmentText){...}

并在PS提示符或加载此功能的脚本中调用它(可以是硬编码,也可以是 可以从导入的模块中获得更好的效果)

$someVariable = Get-StringTime -AppointmentText '9th annual fundraiser - (8am - 3pm)'
Write-Output $someVariable

这将需要剪切我添加的代表某些可能情况的硬编码示例,从$a1$a5,然后将$arrs更改为$arrs = @($AppointmentText)或其他方式,直到您喜欢什么。

请注意,这不考虑军事风格的时间XX:XX或时间字符串中:前有2位数字的排列。

如果您有任何疑问,请告诉我