这是地址方法
数字可能不同12
或412
以及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$
答案 0 :(得分:3)
我通常建议使用正则表达式capture-groups
,这样您就可以将匹配问题分解并简化为较小的集合。在大多数情况下,我使用\d
和\w
,s
来匹配数字,标准字母和空格。
在将代码放入代码之前,我通常会在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;)