我正在开发一个匹配许多不同类型的位置坐标的正则表达式。到目前为止,它匹配了大约90%的格式:
([SNsn][\\s]*)?((?:[\\+-]?[0-9]*[\\.,][0-9]+)|(?:[\\+-]?[0-9]+))(?:(?:[^ms'′""″,\\.\\dNEWnew]?)|(?:[^ms'′""″,\\.\\dNEWnew]+((?:[\\+-]?[0-9]*[\\.,][0-9]+)|(?:[\\+-]?[0-9]+))(?:(?:[^ds°""″,\\.\\dNEWnew]?)|(?:[^ds°""″,\\.\\dNEWnew]+((?:[\\+-]?[0-9]*[\\.,][0-9]+)|(?:[\\+-]?[0-9]+))[^dm°'′,\\.\\dNEWnew]*))))([SNsn]?)[^\\dSNsnEWew]+([EWew][\\s]*)?((?:[\\+-]?[0-9]*[\\.,][0-9]+)|(?:[\\+-]?[0-9]+))(?:(?:[^ms'′""″,\\.\\dNEWnew]?)|(?:[^ms'′""″,\\.\\dNEWnew]+((?:[\\+-]?[0-9]*[\\.,][0-9]+)|(?:[\\+-]?[0-9]+))(?:(?:[^ds°""″,\\.\\dNEWnew]?)|(?:[^ds°""″,\\.\\dNEWnew]+((?:[\\+-]?[0-9]*[\\.,][0-9]+)|(?:[\\+-]?[0-9]+))[^dm°'′,\\.\\dNEWnew]*))))([EWew]?)
测试格式:
N 45°55.732 W 122°29.882
N 047°38.938',W 122°20.887'
40.123,-74.123
40.123°N 74.123°W
40°7'22.8“N 74°7'22.8”W
40°7.38', - 74°7.38'
N40°7'22.8,W74°7'22.8“
40°7'22.8“N,74°7'22.8”W
40 7 22.8,-74 7 22.8
40.123 -74.123
40.123°,-74.123°
144442800,-266842800
40.123N74.123W
4007.38N7407.38W
40°7'22.8“N,74°7'22.8”W
400722.8N740722.8W
N 40 7.38 W 74 7.38
40:7:23N,74:7:23W
40:7:22.8N 74:7:22.8W
40°7'23“N 74°7'23”W
40°7'23“-74°7'23”
40d 7'23“N 74d 7'23”W
40.123N 74.123W
40°7.38,-74°7.38
测试是否有效:https://regexr.com/3ivu2
正如您所看到的,空格和逗号存在问题导致正则表达式与某些格式不匹配。
我正在尝试匹配坐标字符串,以便可以在我的iOS
应用中突出显示它们,并允许用户点按它们。
如何更新正则表达式并修复匹配问题?
答案 0 :(得分:0)
我确信有很多方法可以解决这个问题。由于您尚未指定正则表达式引擎或编程语言,因此我将发布一个适用于PCRE的内容以及在大多数引擎中应该起作用的内容。 PCRE正则表达式比非PCRE正则表达式更容易理解,但两者都使用完全相同的逻辑。
下面定义的模式与您在问题中呈现的每个字符串相匹配,并正确地分隔坐标(x,y)的每个部分。
此方法使用DEFINE
构造来预定义模式。这种结构的优点在于,您可以在一个位置定义正则表达式的可重用部分,因此,您只需编辑这些子模式即可编辑大多数正则表达式。
(?(DEFINE)
(?<ns>[ns])
(?<ew>[ew])
(?<d>[°´’'"d:])
(?<n>[+-]?\d+(?:\.\d+)?)
)
(
(?&ns)?
(?:\ ?(?&n)(?&d)?){1,3}
\ ?(?&ns)?
)
\ ?,?\ ?
(
(?&ew)?
(?:\ ?(?&n)(?&d)?){1,3}
\ ?(?&ew)?
)
标志:gix
(
[ns]?
(?:\ ?[+-]?\d+(?:\.\d+)?[°´’'"d:]?){1,3}
\ ?[ns]?
)
\ ?,?\ ?
(
[ew]?
(?:\ ?[+-]?\d+(?:\.\d+)?[°´’'"d:]?){1,3}
\ ?[ew]?
)
标志:gix
。
某些引擎没有x
标志。对于那些引擎,您可以使用以下单行(as seen here):
([ns]?(?: ?[+-]?\d+(?:\.\d+)?[°´’'"d:]?){1,3} ?[ns]?) ?,? ?([ew]?(?: ?[+-]?\d+(?:\.\d+)?[°´’'"d:]?){1,3} ?[ew]?)
由于两种模式基本相同(非PCRE只是PCRE的扩展版本),我将定义PCRE正则表达式模式,因为它更容易掌握。
请注意,使用x
的模式已转义空格,因为它们会被忽略(x
忽略模式中的空格)。 i
标志允许我们匹配文本而不管大小写(i
使我们的模式不区分大小写)。
(?(DEFINE)...)
正则表达式完全忽略DEFINE
组。它被视为var name=value
,而您可以通过其名称来回忆使用的特定模式。(?<ns>[ns])
群组ns
匹配集nsNS
(?<ew>[ew])
群组ew
匹配集ewEW
(?<d>[°´’'"d:])
群组d
匹配集°´’'"d:
(?<n>[+-]?\d+(?:\.\d+)?)
组n
匹配与以下结构匹配的任何数字
[+-]?
可选择匹配集+-
\d+
匹配一个或多个数字(?:\.\d+)?
可选择匹配小数点后跟一个或多个数字图案由3个较大的部分组成。第一个和最后一个是捕获组(坐标本身),第二个是将两者分开的。
(?&ns)?
可选择匹配论坛ns
(?:\ ?(?&n)(?&d)?){1,3}
匹配[可选空格,然后是群组n
,然后可选地将群组d
]匹配一到三次\ ?(?&ns)?
(可选)匹配空格,可选择匹配组ns
\ ?,?\ ?
匹配可选空格,逗号和空格(这将分隔每个坐标部分)ns
替换为组ew
答案 1 :(得分:0)
这个简化的正则表达式字面上匹配了您给出的所有模式:
^((?:[NW]? ?(?:[-\d.d]+[NW:°´’'",]?[ NW]?)+[, ]*)+[NW]?)$
我不是坐标专家,但如果我没有考虑到某些细节,你可以轻松修改它。
完整测试为here。