猿问

如何在正则表达式中重复分组

我正在搜索从这样的文本中提取坐标:


"xxxxxxx 453740N0093059E 453356N0093503E 

453225N0094201E 453238N0095044E 453351N0095543E 453618N0095826E 

453740N0093059 yyyyyyy 453351N0095543E 453740N0093059 

pppppppp 453740N0093059E 453740N0093059 nnnnnn 

nnnnnn 453618N0095826E 453740N0093059 453225N0094201E ...."

其中 xxx、yyy、nnn 和 ppp 可以是任何单词。


我需要提取 [0-9]{6}N[0-9]{7}E 形式的任何内容并创建一组连续坐标,以便我可以获得:


1: 453740N0093059E 453356N0093503E 453225N0094201E 453238N0095044E 453351N0095543E 453618N0095826E 453740N0093059 

2: 453351N0095543E 453740N0093059 

3: 453740N0093059E 453740N0093059 

4: 453618N0095826E 453740N0093059 453225N0094201E ....

5: ...

...

不知道存在多少个坐标组。


我试图实现正则表达式


preg_match_all("/[0-9]{6}N[0-9]{7}E\s([0-9]{6}N[0-9]{7}E)*?/",$text,$res)

但它返回的 Array 每个索引只有一个坐标,而不是一组连续的坐标。


萧十郎
浏览 305回答 2
2回答

拉莫斯之舞

首先,E在您的模式中似乎是可选的,您需要使用?.接下来,您将[0-9]{6}N[0-9]{7}E离开的部分分组\s,这已经阻止了正则表达式甚至尝试匹配连续的空白分隔子模式。您需要使用(?:\s[0-9]{6}N[0-9]{7}E?)*来匹配 0 个或多个空格序列,后跟坐标。利用preg_match_all('~(?<!\S)\d{6}N\d{7}E(?:\s\d{6}N\d{7}E?)*(?!\S)~', $s, $matches)或者,如果坐标之间可以有 1 个以上的空格preg_match_all('~(?<!\S)\d{6}N\d{7}E(?:\s+\d{6}N\d{7}E?)*(?!\S)~', $s, $matches)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;^请参阅正则表达式演示。注意(?<!\S)并(?!\S)确保仅在空格内或字符串的开头/结尾处匹配。如果不需要检查此条件,请删除。请注意,您可能需要先收缩-&-标准化字符串中的所有空格,然后使用$re = '~(?<!\S)\d{6}N\d{7}E(?:\s+\d{6}N\d{7}E?)*(?!\S)~';$s = preg_replace('~\s+~u', ' ', $s);if (preg_match_all($re, $s, $matches)) {&nbsp; &nbsp; print_r($matches[0]);}

跃然一笑

我的猜测是,也许您正在尝试编写一些简单的表达式,并针对您可能遇到的各种情况使用逻辑 OR 将它们连接起来,例如:\b([0-9]{6}[NSWE]{1,2}[0-9]{7}[NSWE]{1,2})\b|\b([0-9]{6}[NSWE]{1,2}[0-9]{7})\b虽然不确定。测试$re = '/\b([0-9]{6}[NSWE]{1,2}[0-9]{7}[NSWE]{1,2})\b|\b([0-9]{6}[NSWE]{1,2}[0-9]{7})\b/s';$str = 'xxxxxxx 453740N0093059E 453356N0093503E453225N0094201E 453238N0095044E 453351N0095543E 453618N0095826E453740N0093059 yyyyyyy 453351N0095543E 453740N0093059pppppppp 453740N0093059E 453740N0093059 nnnnnnnnnnnn 453618N0095826E 453740N0093059 453225N0094201E ....';preg_match_all($re, $str, $matches, PREG_SET_ORDER, 0);$output = [];$output["groups"] = [];foreach ($matches as $key => $value) {&nbsp; &nbsp; if ($value[2]) {&nbsp; &nbsp; &nbsp; &nbsp; $output["groups"][2][$key] = $value[2];&nbsp; &nbsp; } else if ($value[1]) {&nbsp; &nbsp; &nbsp; &nbsp; $output["groups"][1][$key] = $value[1];&nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; &nbsp; // The expression can be modified and&nbsp; &nbsp; &nbsp; &nbsp; // Other cases can be added here&nbsp; &nbsp; &nbsp; &nbsp; continue;&nbsp; &nbsp; }}var_dump($output["groups"]);输出array(2) {&nbsp; [1]=>&nbsp; array(10) {&nbsp; &nbsp; [0]=>&nbsp; &nbsp; string(15) "453740N0093059E"&nbsp; &nbsp; [1]=>&nbsp; &nbsp; string(15) "453356N0093503E"&nbsp; &nbsp; [2]=>&nbsp; &nbsp; string(15) "453225N0094201E"&nbsp; &nbsp; [3]=>&nbsp; &nbsp; string(15) "453238N0095044E"&nbsp; &nbsp; [4]=>&nbsp; &nbsp; string(15) "453351N0095543E"&nbsp; &nbsp; [5]=>&nbsp; &nbsp; string(15) "453618N0095826E"&nbsp; &nbsp; [7]=>&nbsp; &nbsp; string(15) "453351N0095543E"&nbsp; &nbsp; [9]=>&nbsp; &nbsp; string(15) "453740N0093059E"&nbsp; &nbsp; [11]=>&nbsp; &nbsp; string(15) "453618N0095826E"&nbsp; &nbsp; [13]=>&nbsp; &nbsp; string(15) "453225N0094201E"&nbsp; }&nbsp; [2]=>&nbsp; array(4) {&nbsp; &nbsp; [6]=>&nbsp; &nbsp; string(14) "453740N0093059"&nbsp; &nbsp; [8]=>&nbsp; &nbsp; string(14) "453740N0093059"&nbsp; &nbsp; [10]=>&nbsp; &nbsp; string(14) "453740N0093059"&nbsp; &nbsp; [12]=>&nbsp; &nbsp; string(14) "453740N0093059"&nbsp; }}如果你想探索/简化/修改表达式,它已在regex101.com 的右上角面板中进行了 解释。如果您愿意,您还可以在此链接中观看它如何与某些示例输入匹配。正则表达式电路jex.im可视化正则表达式:
随时随地看视频慕课网APP
我要回答