我试图为加拿大地址的Powershell写一条正则



这是地址方法

这个数字可能不同的12412finch ave east

有多少个单词
1460 Finch Ave East, Toronto, Ontario, A1A1A1

所以我尝试了

^[0-9]+s+[a-zA-Z]+s+[a-zA-Z]+s+[a-zA-Z]+[,]{1}+s[a-zA-Z]+[,]{1}+s+[a-zA-Z]+[,]{1}+s[A-Za-z]d[A-Za-z][ -]?d[A-Za-z]d$

我通常建议使用Regex capture-groups,因此您可以打破并简化匹配问题到较小的集合。在大多数情况下,我使用dws用于匹配数字,标准字母和Whitespaces。

我通常在将其放入代码之前在https://regex101.com上进行实验,因为它提供了一种很好的互动方式来播放表达式和样本。

关于您的问题我出现的表达是:

$regexp = "^(d+)s*((w+s*)+),s*(w+),s*(w+),s*((wd)*)$"

在PowerShell中,我喜欢使用直接regex类,因为它提供的粒度比标准-match操作员更多。

# Example match and results
$sample = "1460 Finch Ave East, Toronto, Ontario, A1A1A1"
$match = [regex]::Match($sample, $regexp)
$match.Success
$match | Select -ExpandProperty groups | Format-Table Name, Value
# Constructed fields
@{
    number = $match.Groups[1]
    street = $match.Groups[2]
    city = $match.Groups[4]
    state = $match.Groups[5]
    areacode = $match.Groups[6]
}

因此,这将导致$match.Success $true,并且将在Groups列表中显示以下编号capture-groups

Name Value
---- -----
0    1460 Finch Ave East, Toronto, Ontario, A1A1A1
1    1460
2    Finch Ave East
3    East
4    Toronto
5    Ontario
6    A1A1A1
7    A1

用于构建字段,您可以忽略3和7,因为这些是部分组:

Name     Value
----     -----
areacode A1A1A1
street   Finch Ave East
city     Toronto
state    Ontario
number   1460

要添加到mákos的好答案中,我建议使用 name 捕获组和$Matches自动变量。这使得抓住单个字段并将它们变成多个输入字符串的对象非常容易:

function Split-CanadianAddress {
  param(
    [Parameter(Mandatory,ValueFromPipeline)]
    [string[]]$InputString
  )
  $Pattern = "^(?<Number>d+)s*(?<Street>(w+s*)+),s*(?<City>(w+s*)+),s*(?<State>(w+s*)+),s*(?<AreaCode>(wd)*)$"
  foreach($String in $InputString){
    if($String -match $Pattern){
      $Fields = @{}
      $Matches.Keys |Where-Object {$_ -isnot [int]} |ForEach-Object {
        $Fields.Add($_,$Matches[$_])
      }
      [pscustomobject]$Fields
    }
  }
}

$Matches Hashtable将包含编号和命名的捕获组,这就是为什么我在创建pscustomobject

之前仅将命名条目复制到$Fields变量

现在您可以使用它:

PS C:> $sample |Split-CanadianAddress
Street   : Finch Ave East
State    : Ontario
AreaCode : A1A1A1
Number   : 1460
City     : Toronto

我已经更新了模式,以允许城市和州名称中的空间(想想"新威斯敏斯特,不列颠哥伦比亚省"(

最新更新