我正在尝试为[lon,lat]坐标创建一个正则表达式。
代码首先检查输入是否以'['开头。 如果是这样,我们通过正则表达式检查坐标的有效性
/([\[][-+]?(180(\.0{1,15})?|((1[0-7]\d)|([1-9]?\d))(\.\d{1,15})?),[-+]?([1-8]?\d(\.\d{1,15})?|90(\.0{1,15})?)[\]][\;]?)+/gm
[lon,lat]的正则表达式测试,小数点后15位[+ - 180度,+ -90度]
它应匹配:
不应该匹配:
我目前有问题;坐标之间(见4& 5)
答案 0 :(得分:0)
您可以尝试使用此(人类可读)模式:
$pattern = <<<'EOD'
~
(?(DEFINE)
(?<lon> [+-]?
(?:
180 (?:\.0{1,15})?
|
(?: 1(?:[0-7][0-9]?)? | [2-9][0-9]? | 0 )
(?:\.[0-9]{1,15})?
)
)
(?<lat> [+-]?
(?:
90 (?:\.0{1,15})?
|
(?: [1-8][0-9]? | 9)
(?:\.[0-9]{1,15})?
)
)
)
\A
\[ \g<lon> , \g<lat> ] (?: ; \n? \[ \g<lon> , \g<lat> ] )* ;?
\z
~x
EOD;
<强>解释强>:
当你必须处理一个长图案时,你必须重复几次相同的子图案,你可以使用几个功能使它更具可读性。
最为人所知的是使用自由间距模式(x修饰符)允许缩进你想要的模式(所有空格都被忽略)和最终要添加评论。
第二个包括在定义部分(?(DEFINE)...)
中定义子模式,您可以在其中定义稍后将在主模式中使用的命名子模式。
由于我不想重复描述经度数和纬度数的大型子模式,我在定义部分创建了两个名为pattern“lon”和“lat”的模式。要在主模式中使用它们,我只需要编写\g<lon>
和\g<lat>
。
javascript版:
var lon_sp = '(?:[+-]?(?:180(?:\\.0{1,15})?|(?:1(?:[0-7][0-9]?)?|[2-9][0-9]?|0)(?:\\.[0-9]{1,15})?))';
var lat_sp = '(?:[+-]?(?:90(?:\\.0{1,15})?|(?:[1-8][0-9]?|9)(?:\\.[0-9]{1,15})?))';
var coo_sp = '\\[' + lon_sp + ',' + lat_sp + '\\]';
var regex = new RegExp('^' + coo_sp + '(?:;\\n?' + coo_sp + ')*;?$');
var coordinates = new Array('[120,80];',
'[120,80]',
'[180,90];[180,67];',
'[123,34];[-32,21];\n[12,-67]',
'[25,67][76,23];',
'[25,67]\n[76,23]');
for (var i = 0; i<coordinates.length; i++) {
console.log("\ntest "+(i+1)+": " + regex.test(coordinates[i]));
}
答案 1 :(得分:0)
试试这个:
^(\[([+-]?(?!(180\.|18[1-9]|19\d{1}))\d{1,3}(\.\d{1,15})?,[+-]?(?!(90\.|9[1-9]))\d{1,2}(\.\d{1,15})?(\];$|\]$|\];\[)){1,})
演示:http://regex101.com/r/vQ4fE0/7
<强>解释强>
^(\[
必须以括号
开头[+-]?
在数字前面可能包含+ - 也可能不包含+ -
(?!(180\.|18[1-9]|19\d{1}))
不应包含180.
,181-189
或19x
\d{1,3}(\.\d{1,15})?
否则,任何包含1或3位数字的数字,包括或不包含小数(最多15位)
(?!(90\.|9[1-9]))
90检查与此类似,我们不允许90.
或91-99
\d{1,2}(\.\d{1,15})?
否则,任何包含1或2位数字的数字,包括或不包含小数(最多15位)
(\];$|\]$|\];\[)
括号体的结尾必须有一个;
分隔两个括号体,否则它必须是该行的末尾。
{1,}
括号可以存在1次或多次
希望这有用。
答案 2 :(得分:0)
这可能有用。请注意,您有很多捕获组,其中没有一个 由于递归量词,会给你很好的信息。
# /^(\[[-+]?(180(\.0{1,15})?|((1[0-7]\d)|([1-9]?\d))(\.\d{1,15})?),[-+]?([1-8]?\d(\.\d{1,15})?|90(\.0{1,15})?)\](?:;\n?|$))+$/
^
( # (1 start)
\[
[-+]?
( # (2 start)
180
( \. 0{1,15} )? # (3)
|
( # (4 start)
( 1 [0-7] \d ) # (5)
|
( [1-9]? \d ) # (6)
) # (4 end)
( \. \d{1,15} )? # (7)
) # (2 end)
,
[-+]?
( # (8 start)
[1-8]? \d
( \. \d{1,15} )? # (9)
|
90
( \. 0{1,15} )? # (10)
) # (8 end)
\]
(?: ; \n? | $ )
)+ # (1 end)
$
答案 3 :(得分:0)
尝试一种函数方法,其中函数可以为您执行某些拆分,以及将数字比较委托给正则表达式。我在这里测试了它:http://repl.it/YyG/3
//represents regex necessary to capture one coordinate, which
// looks like 123 or 123.13532
// the decimal part is a non-capture group ?:
var oneCoord = '(-?\\d+(?:\\.\\d+)?)';
//console.log("oneCoord is: "+oneCoord+"\n");
//one coordinate pair is represented by [x,x]
// check start/end with ^, $
var coordPair = '^\\['+oneCoord+','+oneCoord+'\\]$';
//console.log("coordPair is: "+coordPair+"\n");
//the full regex string consists of one or more coordinate pairs,
// but we'll do the splitting in the function
var myRegex = new RegExp(coordPair);
//console.log("my regex is: "+myRegex+"\n");
function isPlusMinus180(x)
{
return -180.0<=x && x<=180.0;
}
function isPlusMinus90(y)
{
return -90.0<=y && y<=90.0;
}
function isValid(s)
{
//if there's a trailing semicolon, remove it
if(s.slice(-1)==';')
{
s = s.slice(0,-1);
}
//remove all newlines and split by semicolon
var all = s.replace(/\n/g,'').split(';');
//console.log(all);
for(var k=0; k<all.length; ++k)
{
var match = myRegex.exec(all[k]);
if(match===null)
return false;
console.log(" match[1]: "+match[1]);
console.log(" match[2]: "+match[2]);
//break out if one pair is bad
if(! (isPlusMinus180(match[1]) && isPlusMinus90(match[2])) )
{
console.log(" one of matches out of bounds");
return false;
}
}
return true;
}
var coords = new Array('[120,80];',
'[120.33,80]',
'[180,90];[180,67];',
'[123,34];[-32,21];\n[12,-67]',
'[25,67][76,23];',
'[25,67]\n[76,23]',
'[190,33.33]',
'[180.33,33]',
'[179.87,90]',
'[179.87,91]');
var s;
for (var i = 0; i<coords.length; i++) {
s = coords[i];
console.log((i+1)+". ==== testing "+s+" ====");
console.log(" isValid? => " + isValid(s));
}