我正试图为加拿大地址的powershell写一个正则表达式

时间:2018-03-24 20:14:38

标签: regex powershell street-address

这是地址方法

数字可能不同12412以及finch 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$

2 个答案:

答案 0 :(得分:3)

我通常建议使用正则表达式capture-groups,这样您就可以将匹配问题分解并简化为较小的集合。在大多数情况下,我使用\d\ws来匹配数字,标准字母和空格。

在将代码放入代码之前,我通常会在https://regex101.com上进行实验,因为它提供了一种很好的交互方式来处理表达式和示例。

关于你的问题,我提出的表达是:

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

在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,并且capture-groups列表中会显示以下编号的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

答案 1 :(得分:3)

要添加到mákos excellent answer,我建议使用名为的捕获组和$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>(\w\d)*)$"

  foreach($String in $InputString){
    if($String -match $Pattern){
      $Fields = @{}
      $Matches.Keys |Where-Object {$_ -isnot [int]} |ForEach-Object {
        $Fields.Add($_,$Matches[$_])
      }
      [pscustomobject]$Fields
    }
  }
}

$Matches哈希表将包含编号和命名的捕获组,这就是我在创建$Fields之前仅将命名条目复制到pscustomobject变量的原因

现在您可以使用它:

PS C:\> $sample |Split-CanadianAddress

Street   : Finch Ave East
State    : Ontario
AreaCode : A1A1A1
Number   : 1460
City     : Toronto

我已更新模式以允许城市和州名称中的空格(想想&#34;新威斯敏斯特,不列颠哥伦比亚省&#34;)