已知有三组数据,如下(1).MultiPolygon中含有一个实心的多边形
MultiPolygon
(
    ((-10 0.0, 12.5 20, 5 5, -10 0.0))
)(2).MultiPolygon中含有一个带孔的多边形
MultiPolygon(
    ((10 10,10 20,5 5,10 10),(10 10,10 20 ,5 5,10 10))
)(3).MultiPolygon中含有三个多边形(1.一个带一个孔的;2.一个实心的;3.一个带两个孔的)
MultiPolygon(
    ((10 10,10 20,5 5,10 10),(10 10,10 20,5 5,10 10))
   ,((10 10,10 20,5 5,10 10))
   ,((10 10,10 20,5 5,10 10.1),(10 10,10 20,5 5,10 10),(10 10,10 20,5 5,10 10))
)===================================
说明:
1).坐标值为普通的浮点数(上述表达中所用的数据都是随意的)
2).多边形或孔至少有4个坐标对,否则返回FALSE
3).一个多边形带的孔的个数不是固定的
4).能出现空格的地方则不能限制空格的个数
5).上面三组数据都是以一行字符串的形式描述的,只是为了方便大家查看,故做对齐状!

要求:
   请写一个正式表达式,以完成对上述三种情况及其他推导出的可适应情况的正确匹配!
PS:以下是本人所写的正则,但通过window.alert()函数发现,拼成的字符串太长了...
function isMultiPolygon(wellKnownText)
{
    var floatPattern="-?(0|0\\.\\d+|[1-9]\\d*\\.\\d+|[1-9]\\d*)";
    var mpgCommon="[ ]*\\,[ ]*"+floatPattern+"[ ]*"+floatPattern+"[ ]*";  //公共部分,示例: " ,10 3.8 "
    var mpgHead="^[ ]*MultiPolygon[ ]*\\([ ]*";
    var mpgPartSoild="[ ]*\\([ ]*" + "\\([ ]*"+floatPattern+"[ ]+"+floatPattern+"[ ]*\("+mpgCommon+"\){3,}"+"\\)"; //比Polygon多一个左括号
    var mpgPartHoles="[ ]*\([ ]*"+"[ ]*\\,[ ]*\\([ ]*"+floatPattern+"[ ]+"+floatPattern+"[ ]*\("+mpgCommon+"\){3,}"+"\\)[ ]*\)*" + "[ ]*\\)[ ]*"; //比Polygon多一个右括号
    var mpgFirst=mpgPartSoild+mpgPartHoles; //MultiPolygon中的第一个多边形(有且仅有一个)
    var mpgAfterFirst="\([ ]*\\,"+mpgPartSoild+mpgPartHoles+"\)*"; //(任意个)
    var mpgTail="[ ]*\\)[ ]*$";
    var multiPolygon_String=mpgHead+mpgFirst+mpgAfterFirst+mpgTail;
    var multiPolygon_Pattern=new RegExp(multiPolygon_String,"i");  //创建忽略大小写的正则表达式
    window.alert(multiPolygon_Pattern);
    return multiPolygon_Pattern.test(wellKnownText);
}
故:希望哪位大哥能够帮助简化一下!!

解决方案 »

  1.   

    补充:JS代码中的注释
     第4行的"//比Polygon多一个左括号"

     第5行的"//比Polygon多一个右括号"大家可忽略不计!
      

  2.   


    // 换个思路行不行呢
    function isMultiPolygon(txt) {
    var str = txt.replace(/[^MultiPolygon(),.\s\d]/ig, "");  // 不能出现的字符先过滤掉
    if (str != txt) return false; // 不与原字符串相等, 直接返回 false // 所有浮点数替换为 NUMBER
    str = str.replace(/\-?(?:0|[1-9]\d*)(?:\.\d*)?/g, "NUMBER");
    // 所有座标对替换为 POINT
    str = str.replace(/NUMBER\s+NUMBER/g, "POINT");
    // 所有多边形或孔替换为 CIRCLE
    str = str.replace(/\(\s*POINT(?:\s*\,\s*POINT){3,}\s*\)/g, "CIRCLE");
    // 所有有孔或无孔多边形替换为 POLY
    str = str.replace(/\(\s*CIRCLE(?:\s*\,\s*CIRCLE)*\s*\)/g, "POLY");  // alert(str);
    return /^\s*MultiPolygon\s*\(\s*POLY(\s*\,\s*POLY)*\s*\)\s*$/ig.test(str);
    }
      

  3.   

    var str = txt.replace(/[^MultiPolygon(),.\s\d\-]/ig, "");  // 不能出现的字符先过滤掉呵呵,还有个负号漏了
      

  4.   

    (1)是个比较特殊的情况,这个可以单独考虑下面是一般的情况
    var a ='MultiPolygon(((10 10,10 20,5 5,10 10),(10 10,10 20 ,5 5,10 10)))'如上,首先去掉 MultiPolygon(  和 )就是形如 ((10 10,10 20,5 5,10 10),(10 10,10 20 ,5 5,10 10))
    再去掉开头和结尾的括号,然后split('),')就可以得到一个数组
    然后对每个数组用正则判断就行了
      

  5.   

    看来 wcwtitxu 痞子 的方法更独特,而且方便代码以后的维护。呵呵
      

  6.   


    浮点数: [+-]?\d+(\.+?\d+)?
    有4个坐标对以上: ([+-]\d+(\.+?\d+)?)(\s+([+-]\d+(\.+?\d+)?)){3,}
    不能限制空格的个数: \s+
    任意多层(无限层)嵌套, 得算匹配数现在忘了, 像是 (?<p>) ... (?<-p>)
      

  7.   

    TO:wcwtitxu 痞子如果我希望多边形或孔必须是闭合的呢??
    所谓闭合:意思就是多边形或孔的第一个坐标对和最后一个坐标对必须一致,如下:(1 1, 1 0, 2 4 ,5 7 ,1 1)
    请赐教!!!
      

  8.   

    送上解析步骤:<script language="javascript">
    var a1="MultiPolygon(((-10 0.0, 12.5 20, 5 5, -10 0.0)))";
    var a2="MultiPolygon(((10 10,10 20,5 5,10 10),(10 10,10 20 ,5 5,10 10)))";
    var a3="MultiPolygon(((10 10,10 20,5 5,10 10),(10 10,10 20,5 5,10 10)),((10 10,10 20,5 5,10 10)),((10 10,10 20,5 5,10 10.1),(10 10,10 20,5 5,10 10),(10 10,10 20,5 5,10 10)))";//Step 1: 孔
    //var rx1=/((([+-]?\d+(\.+?\d+)?)\s+([+-]?\d+(\.+?\d+)?))(\s*,\s*(([+-]?\d+(\.+?\d+)?)\s+([+-]?\d+(\.+?\d+)?))){3,})/g//Step 2: 多孔
    //var rx2=/(\((([+-]?\d+(\.+?\d+)?)\s+([+-]?\d+(\.+?\d+)?))(\s*,\s*(([+-]?\d+(\.+?\d+)?)\s+([+-]?\d+(\.+?\d+)?))){3,}\))(\s*,\s*\(((([+-]?\d+(\.+?\d+)?)\s+([+-]?\d+(\.+?\d+)?))(\s*,\s*(([+-]?\d+(\.+?\d+)?)\s+([+-]?\d+(\.+?\d+)?))){3,}\)))*/g//Step 3: 多组合
    //var rx3=/(\((\((([+-]?\d+(\.+?\d+)?)\s+([+-]?\d+(\.+?\d+)?))(\s*,\s*(([+-]?\d+(\.+?\d+)?)\s+([+-]?\d+(\.+?\d+)?))){3,}\))(\s*,\s*\(((([+-]?\d+(\.+?\d+)?)\s+([+-]?\d+(\.+?\d+)?))(\s*,\s*(([+-]?\d+(\.+?\d+)?)\s+([+-]?\d+(\.+?\d+)?))){3,}\)))*\))(\s*,\s*(\((\((([+-]?\d+(\.+?\d+)?)\s+([+-]?\d+(\.+?\d+)?))(\s*,\s*(([+-]?\d+(\.+?\d+)?)\s+([+-]?\d+(\.+?\d+)?))){3,}\))(\s*,\s*\(((([+-]?\d+(\.+?\d+)?)\s+([+-]?\d+(\.+?\d+)?))(\s*,\s*(([+-]?\d+(\.+?\d+)?)\s+([+-]?\d+(\.+?\d+)?))){3,}\)))*\)))*/g//Step 4: 给合命令函数
    var rx4=/MultiPolygon\((\((\((([+-]?\d+(\.+?\d+)?)\s+([+-]?\d+(\.+?\d+)?))(\s*,\s*(([+-]?\d+(\.+?\d+)?)\s+([+-]?\d+(\.+?\d+)?))){3,}\))(\s*,\s*\(((([+-]?\d+(\.+?\d+)?)\s+([+-]?\d+(\.+?\d+)?))(\s*,\s*(([+-]?\d+(\.+?\d+)?)\s+([+-]?\d+(\.+?\d+)?))){3,}\)))*\))(\s*,\s*(\((\((([+-]?\d+(\.+?\d+)?)\s+([+-]?\d+(\.+?\d+)?))(\s*,\s*(([+-]?\d+(\.+?\d+)?)\s+([+-]?\d+(\.+?\d+)?))){3,}\))(\s*,\s*\(((([+-]?\d+(\.+?\d+)?)\s+([+-]?\d+(\.+?\d+)?))(\s*,\s*(([+-]?\d+(\.+?\d+)?)\s+([+-]?\d+(\.+?\d+)?))){3,}\)))*\)))*\)/g/*
    alert(a1.replace(rx1, "--"));
    alert(a2.replace(rx1, "--"));
    alert(a3.replace(rx1, "--"));alert(a1.replace(rx2, "--"));
    alert(a2.replace(rx2, "--"));
    alert(a3.replace(rx2, "--"));alert(a1.replace(rx3, "--"));
    alert(a2.replace(rx3, "--"));
    alert(a3.replace(rx3, "--"));
    */alert("["+ a1.replace(rx4, "--") + "]");
    alert("["+ a2.replace(rx4, "--") + "]");
    alert("["+ a3.replace(rx4, "--") + "]");</script>
      

  9.   

    源数据不知还有哪些情况, 改天再分析, 现在要睡觉了... zzZZzz
      

  10.   

    <script language="javascript">var rx4=/MultiPolygon\((\((\((([+-]?\d+(\.+?\d+)?)\s+([+-]?\d+(\.+?\d+)?))(\s*,\s*(([+-]?\d+(\.+?\d+)?)\s+([+-]?\d+(\.+?\d+)?))){3,}\))(\s*,\s*\(((([+-]?\d+(\.+?\d+)?)\s+([+-]?\d+(\.+?\d+)?))(\s*,\s*(([+-]?\d+(\.+?\d+)?)\s+([+-]?\d+(\.+?\d+)?))){3,}\)))*\))(\s*,\s*(\((\((([+-]?\d+(\.+?\d+)?)\s+([+-]?\d+(\.+?\d+)?))(\s*,\s*(([+-]?\d+(\.+?\d+)?)\s+([+-]?\d+(\.+?\d+)?))){3,}\))(\s*,\s*\(((([+-]?\d+(\.+?\d+)?)\s+([+-]?\d+(\.+?\d+)?))(\s*,\s*(([+-]?\d+(\.+?\d+)?)\s+([+-]?\d+(\.+?\d+)?))){3,}\)))*\)))*\)/function imkCheck(strCommand)
    {
    return rx4.test(a3);
    }var a1="MultiPolygon(((-10 0.0, 12.5 20, 5 5, -10 0.0)))";
    var a2="MultiPolygon(((10 10,10 20,5 5,10 10),(10 10,10 20 ,5 5,10 10)))";
    var a3="MultiPolygon(((10 10,10 20,5 5,10 10),(10 10,10 20,5 5,10 10)),((10 10,10 20,5 5,10 10)),((10 10,10 20,5 5,10 10.1),(10 10,10 20,5 5,10 10),(10 10,10 20,5 5,10 10)))";alert(imkCheck(a1));
    alert(imkCheck(a2));
    alert(imkCheck(a3));</script>
      

  11.   

    又看了一下function isMultiPolygon(txt) {
    var str = txt.replace(/[^MultiPolygon(),.\s\d\-]/ig, "");  // 不能出现的字符先过滤掉
    if (str != txt) return false; // 不与原字符串相等, 直接返回 false str = str.replace(/\s*?([(, )]|^|$)\s*/g, "$1"); // 去掉无所谓的空格
    // alert(str);
    txt = str.replace(/0*(\d+)(?:\.0*|(\.\d*?)0*)?(\D)/g, "$1$2$3");  // 去掉数字中无所谓的 0
    // alert(txt);

    str = txt.replace(/\-?\d+(?:\.\d*)?/g, "NUMBER");
    str = str.replace(/NUMBER NUMBER/g, "POINT");
    str = str.replace(/\(POINT(?:,POINT){3,}\)/g, "CIRCLE");
    str = str.replace(/\(CIRCLE(?:\,CIRCLE)*\)/g, "POLY");
    if (!/^MultiPolygon\(POLY(?:\,POLY)*\)$/ig.test(str))
    return false; // 有未闭合的多边形或孔 返回false, 无则返回 true 
    return !(/\(([\d. ]+),[^)]+\,(?!\1\))([^),]+)\)/.test(txt));
    }
      

  12.   

    呵呵,更正一下    return !(/\(([^(),]+),[^)]+\,(?!\1\))([^),]+)\)/.test(txt));
      

  13.   

    请问能给讲讲这2句
    str = str.replace(/\s*?([(, )]|^|$)\s*/g, "$1"); // 去掉无所谓的空格
    txt = str.replace(/0*(\d+)(?:\.0*|(\.\d*?)0*)?(\D)/g, "$1$2$3");  // 去掉数字中无所谓的 0
    的意思吗?"$1" 和 "$1$2$3" ; 是什么意思啊?为什么替换成那种格式的?
      

  14.   

    晕!!!这个都不懂
    str.replace(/0*(\d+)(?:\.0*|(\.\d*?)0*)?(\D)/g, "$1$2$3");  /
    这里的$1就是红色部分
      

  15.   

    恩 $1...$n 分表别示  捕获组1...捕获组n   的内容
    如:var str = "-----*AABBCC*-----*aaaabbbbbcccc*-----";var regex = /\*(A+)(?:B+)(C+)\*/ig
    // 正则中 A+ 和 C+ 分别被括号括起来  所以分别是 捕获组1 和 捕获组2
    // B+ 虽然也被括号包括       但是加了 ?: 就表示非捕获组, 其匹配到的内容就不捕获了
    alert(str.replace(regex, "[X]"));
    // 当然看到 "-----[X]-----[X]-----" 了
    alert(str.replace(regex, "[$1 & $2]"))
    // 第一次 $1 捕获到的是 AA           $2 捕获到的内容是 CC       [$1 & $2] 就是 "[AA & CC]"
    // 第一次 $1 捕获到的是 aaaa         $2 捕获到的内容是 cccc     [$1 & $2] 就是 "[aaaa & cccc]"
    // 看到 "-----[AA & CC]-----[aaaa & cccc]-----"// 别外还有 $' $` $& $+ 难表述,不说了
      

  16.   


    <script language="javascript">
    var b1="(1 1, 1 0, 2 4 ,5 7 ,1 1)";
    var b2="(1 1, 1 0, 2 4 ,5 7 ,1 2)";
    var b3="(1 2, 1 0, 2 4 ,5 7 ,1 1)";//闭合测试
    var rxv=/\(((?:[+-]?\d+(?:\.+?\d+)?)\s+(?:[+-]?\d+(?:\.+?\d+)?))(?:\s*,\s*(?:[+-]?\d+(?:\.+?\d+)?)\s+(?:[+-]?\d+(?:\.+?\d+)?)){2,}(?:\s*,\s*\1)\)/alert(imkCheck(b1));
    alert(imkCheck(b2));
    alert(imkCheck(b3));
    function imkCheck(strCommand)
    {
    return rxv.test(strCommand);
    }
    </script>
      

  17.   

    TO:wcwtitxu 痞子
    多谢你的热心指点!!!请到
    http://topic.csdn.net/u/20090505/14/1e171b80-1c41-4882-b035-904959065e75.html
    接分。
      

  18.   

    e 测试了果然有 bugfunction isMultiPolygon(txt) {
        if (/[^MultiPolygon(),.\s\d\-]/g.test(txt)) return false;    txt = txt.replace(/^\s*|\s*$|\s*([)(,\s])\s*/g, "$1"); // 换了一个去的空格的正则
        txt = txt.replace(/0*(\d+)(?:\.0*|(\.\d*?)0*)?(\D)/g, "$1$2$3");    var str = txt.replace(/\-?\d+(?:\.\d*)?/g, "NUMBER");
        str = str.replace(/NUMBER\sNUMBER/g, "POINT");  //两NUMBER间换成\s因为有可能是换行符或制表符,这也是开始考虑不周
        str = str.replace(/\(POINT(?:,POINT){3,}\)/g, "CIRCLE");
        str = str.replace(/\(CIRCLE(?:\,CIRCLE)*\)/g, "POLY");    return /^MultiPolygon\(POLY(?:\,POLY)*\)$/ig.test(str) &&
            !(/\(([\d. ]+),[^)]+\,(?!\1\))([^),]+)\)/.test(txt));
    }
      

  19.   

    txt = txt.replace(/^\s*|\s*$|\s*([)(,\s])\s*/g, "$1"); // 换了一个去的空格的正则这个简化为txt = txt.replace(/\s*([)(,\s])\s*/g, "$1"); 
      

  20.   

    这里简了许多 不过测试时发现var reg = /\s*([)(,\s])\s*/g;
    var txt = "    MultiPolygon (((-10 0.0, 12.5 20, 5 5, -10 0.0)) )     ";
    txt = "X" + txt.replace(reg, "$1") + "X";
    alert(txt); // 其它的都正确, 就前面"X"和"MultiPolygon..."之间还有一个空格,就是说没有达到trimLeft的效果