“-match” 不如期望的那样匹配,寻求建议

huangapple go评论65阅读模式
英文:

powershell "-match" not matching as hoped, seeking advice

问题

以下是修复的匹配字符串,以及原因:

$fileName = "Youghusband Friends 2012-12-14 003.jpg"
if ($fileName -match '(\d{1,2}|\d{2})[-_.](\d{1,2}|\d{2})[-_.](\d{4}).*') {
    $matchedPart = $matches[0]
    Write-Host "FILE_MATCH_C (c) ALL: '$fileName' Matched Part: '$matchedPart' matches[1..3]='${matches[1]}-${matches[2]}-${matches[3]}'"
} elseif ($fileName -match '(\d{4})[-_.](\d{1,2}|\d{2})[-_.](\d{1,2}|\d{2}).*') {
    $matchedPart = $matches[0]
    Write-Host "FILE_MATCH_D (d) ALL: '$fileName' Matched Part: '$matchedPart' matches[1..3]='${matches[1]}-${matches[2]}-${matches[3]}'"
} else {
    Write-Host "FILE_NO_MATCH: '$fileName'"
}

修复的匹配字符串主要改变了正则表达式中的模式。现在,匹配字符串不再包括字符串的开头和结束的锚点(^$),因此可以匹配日期字符串出现在文件名中的任何位置。此外,我们还将匹配后面的任意字符((.*))移到了正则表达式之外。

希望这能解决你的问题。

英文:

I have a need to rename files and folders based on a date anywhere in the name/folder string, front/middle/end.

The date formats can be like:

  • DD-MM-YYYY
  • D-M-YYYY
  • D-MM-YYYY
  • DD-M-YYYY
  • YYYY-MM-DD
  • YYYY-M-D
  • YYYY-MM-D
  • YYYY-M-DD

and intra-date separators can be any of these 3 characters

  • - (dash)
  • _ (underscore)
  • . (period)

I had thought the match strings below (provided by ChatGPT) would do the trick but no.
It only matches if the date is at the start of a string.

$fileName = "Youghusband Friends 2012-12-14 003.jpg"
	if ($fileName -match  '^(\d{1,2}|\d{2})[-_.](\d{1,2}|\d{2})[-_.](\d{4})(.*)$') {
        $matchedPart = $matches[0]
        Write-Host "FILE_MATCH_C (c) ALL: '$fileName'		Matched Part: '$matchedPart'	 matches[1..3]='$matches[1..3]'"
	} elseif ($fileName -match '^(\d{4})[-_.](\d{1,2}|\d{2})[-_.](\d{1,2}|\d{2})(.*)$') {
        $matchedPart = $matches[0]
        Write-Host "FILE_MATCH_D (d) ALL: '$fileName'		Matched Part: '$matchedPart'	 matches[1..3]='$matches[1..3]'"
	} else {
		Write-Host "FILE_NO_MATCH: '$fileName'"
	}

Result:

FILE_NO_MATCH: 'Youghusband Friends 2012-12-14 003.jpg'

What match strings would fix it ? (and why)

Thanks

答案1

得分: 3

你的正则表达式存在问题,主要是使用了 ^(行的开头)和 $(行的结尾),而不是使用单词边界(\b)。以下是如何使用单个正则表达式来处理你的代码的方式:

$re = '(?x)
\b(?:
    (?<day>[0-9]{1,2})[-_.]
    (?<month>[0-9]{1,2})[-_.]
    (?<year>[0-9]{4})
  |
    (?<year>[0-9]{4})[-_.]
    (?<month>[0-9]{1,2})[-_.]
    (?<day>[0-9]{1,2})
)\b'

$fileName = 'Youghusband Friends 2012-12-14 003.jpg'

if ($fileName -match $re) {
    # 如果你想将其作为日期时间实例,你可以这样做:
    # [datetime]::new($Matches['year'], $Matches['month'], $Matches['day'])

    [pscustomobject]@{
        date  = $Matches[0]
        year  = $Matches['year']
        month = $Matches['month']
        day   = $Matches['day']
    }
}
else {
    Write-Host "FILE_NO_MATCH: '$fileName'"
}

有关正则表达式详细信息,请参见 https://regex101.com/r/R0EkUj/1

英文:

The clear issue with your regex is the use of ^ (start of the line) and $ (end of the line) instead of using word boundaries (\b). Here is how you could approach your code with a single regex:

$re = &#39;(?x)
\b(?:
    (?&lt;day&gt;[0-9]{1,2})[-_.]
    (?&lt;month&gt;[0-9]{1,2})[-_.]
    (?&lt;year&gt;[0-9]{4})
  |
    (?&lt;year&gt;[0-9]{4})[-_.]
    (?&lt;month&gt;[0-9]{1,2})[-_.]
    (?&lt;day&gt;[0-9]{1,2})
)\b&#39;

$fileName = &#39;Youghusband Friends 2012-12-14 003.jpg&#39;

if ($fileName -match $re) {
    # if you want to have it as a datetime instace, here you can do:
    # [datetime]::new($Matches[&#39;year&#39;], $Matches[&#39;month&#39;], $Matches[&#39;day&#39;])

    [pscustomobject]@{
        date  = $Matches[0]
        year  = $Matches[&#39;year&#39;]
        month = $Matches[&#39;month&#39;]
        day   = $Matches[&#39;day&#39;]
    }
}
else {
    Write-Host &quot;FILE_NO_MATCH: &#39;$fileName&#39;&quot;
}

See https://regex101.com/r/R0EkUj/1 for regex details.

huangapple
  • 本文由 发表于 2023年6月19日 12:42:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/76503659.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定