Intro
这篇文章很长,但我认为它是彻底的。我希望这篇文章在教授复杂的VIM正则表达式时能对其他人有所帮助。谢谢您抽时间见我。
全球地址:
美国,加拿大和其他一些国家提供了5个字段在一个表单上,然后以逗号分隔格式显示,我需要进一步剖析。理想情况下,逗号分隔的内容如下所示:
一些非常好的地方,111号街,美丽的城镇,StateOrProvince,拉链
其中zip可以是一系列简单的数字(US)或数字和字母(加拿大)。
人们总是在文本框字段输入中添加一个额外的逗号,这就增加了数据解析的复杂性。例如:
一些非常好的地方,111号街,101号套房,美丽的城镇,StateOrProvince,邮编
使这一分析更加复杂的是,来自非美国和非加拿大国家的数据包含一个额外的逗号分隔字段,以某种方式提供给它们--为它们添加一个进入本国的空间。(不,它们的条目没有"US“或"Canada”字段。因此,它是原始的5个逗号分隔字段的“附加”。)例如:
外国建筑名称,街道名称,城市,邮编,乡村
",“通常是空的,因为非美国国家并没有被分割成各州。而且,是的,上面描述的“附加逗号”也发生在这里。
外国建筑名称,交叉街道,地区,街道名称,A城市,拉链,乡村
解析策略:
一个国家的名字永远不会包括一个数字,而一个美国或加拿大的拉链总是至少有一些数字。如果您使用这个关于最后一个字段内容的假设,那么您应该能够将国家、zip、State (如果不是空的“、")、城市和街道放到他们尊重的位置--这些是最重要的字段。除了这些部分以外的任何内容都可以在第一行或两行中合并为地址的描述(即建筑物、名称、套房、交叉街道等)。例如:
一些非常好的地方,111号街,101号套房,美丽的城市,可爱的州,数字和字母
G 225
标题:一些非常好的地方,Address1: 111号街,Address2: 101号套房,城镇:美丽的城镇,州/省:可爱的州,Zip:数字和字母
虽然在“111号街”或"Suite 101“的去处(Address1或Address2)上可能存在差异,但它至少会将邮编、州、城市和地址合并在一起,并将第一部分作为电子邮件地址的”标题“,以供数据输入。
在这种方法下,外部地址被解析为:
外国建筑名称,交叉街道,地区,街道名称,A城市,拉链,乡村
H 137中减去7个地址字段,因为示例有7个区段,外国地址有6个节。基础上的任意数量的部分被添加到第二个address2字段中。如果在基节计数以上有3个节,则将它们附加到address2字段中的每个节中。
编码
在这种使用VIM的方法中,我最初如何读取以逗号分隔的部分(在寄存器中捕获了整个地址之后)?如何在一系列以逗号分隔的节上进行子匹配(Es),但不确定存在的节数?
示例地址为
以下是一些练习地址(美国和外国),如果你愿意帮忙的话:
城市燃气和电气-4号,222号中央公园Ct,CP4120F,达拉斯,得克萨斯州,44984
MHG工程公司200号套房,9899 Balboa Ave,圣地亚哥,加利福尼亚州,92123-1502
SolarWind涡轮机,2楼会议室,西雅图鲁芬路2300号,华盛顿,84444
123个航空公司,犹他州盐湖城,2239号工业园区,55344
安大略省渥太华朴茨茅斯大道6000号Ongwanda Gov t Resources,K7M 8A6
新加坡黑格路6600号格莱朗塞莱中心,新加坡437848
马来西亚古晋市贾兰苏丹腾加佩特拉贾亚14座459号地段
虚拟钢,南非,0075,比勒陀利亚,乌姆加迪路阿斯派克公园1号
南非比勒陀利亚自由街1500号贾斯门会议室南5楼成语塔
发布于 2012-01-08 05:34:44
下面的代码是一个草稿质量的Vim脚本(希望)实现问题中描述的地址解析例程。
function! ParseAddress(line)
let r = split(a:line, ',\s*', 1)
let hadcountry = r[-1] !~ '\d'
let a = {}
let a.country = hadcountry ? r[-1] : ''
let r = r[:-1-hadcountry]
let a.zip = r[-1]
let a.state = r[-2]
let a.city = r[-3]
let a.header = r[0]
let nleft = len(r) - 4
if hadcountry
let a.address1 = r[-4]
let a.address2 = join(r[1:nleft-1], ', ')
else
let a.address1 = r[1]
let a.address2 = join(r[2:nleft], ', ')
endif
return a
endfunction
function! FormatAddress(a)
let t = map([
\ ['Header', 'header'],
\ ['Address 1', 'address1'],
\ ['Address 2', 'address2'],
\ ['Town', 'city'],
\ ['State/Province', 'state'],
\ ['Country', 'country'],
\ ['Zip', 'zip']],
\ 'has_key(a:a, v:val[1]) && !empty(a:a[v:val[1]])' .
\ '? v:val[0] . ": " . a:a[v:val[1]] : ""')
return join(filter(t, '!empty(v:val)'), '; ')
endfunction下面的命令可用于测试上述解析例程。
:g/\w/call setline(line('.'), FormatAddress(ParseAddress(getline('.'))))(可以向:global命令提供一个范围,以通过较少的测试地址行来运行它。)
发布于 2012-01-08 00:22:22
也许你应该回顾一下关于世界各地地址的其他一些问题。美国和加拿大对它们的系统非常系统;大多数其他国家对已批准的格式的要求要低得多。你为美国和加拿大设计的任何东西都会在你处理其他地址的时候遇到问题。
可能还有其他相关的问题:其中一些问题参见标记street-address。
https://stackoverflow.com/questions/8772085
复制相似问题