这是地址方法
这个数字可能不同的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$
我通常建议使用Regex capture-groups
,因此您可以打破并简化匹配问题到较小的集合。在大多数情况下,我使用d
和w
,s
用于匹配数字,标准字母和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
我已经更新了模式,以允许城市和州名称中的空间(想想"新威斯敏斯特,不列颠哥伦比亚省"(