如何用正则匹配前缀+任意多组坐标的LineString并捕获命名组?
正则匹配指定前缀与多组坐标的解决方案
问题描述
- 有多行文本,需识别带指定前缀的行,提取其中多组
lat=X.XXXXXX, lon=X.XXXXXX格式的坐标,生成LineString格式字符串用于C#开发 - 需排除无指定前缀但含坐标的行,同时可提取名称、ID等其他属性
- 现有正则仅能单独匹配坐标,或仅捕获最后一组坐标,无法同时实现前缀匹配+任意多组坐标捕获
测试行示例:
PREFIXafkzh(lat=34.42344, lon=23.6346jsdfkh,lat=2.4234, lon=12.124)
解决方案
C#中,重复的命名捕获组默认仅保留最后一次匹配结果,因此需要通过分阶段匹配或捕获集合来实现需求:
方案1:分阶段匹配(易维护)
筛选目标行:先匹配带指定前缀的行,过滤无关数据
正则示例(前缀为PREFIX):^PREFIX.*解释:匹配所有以
PREFIX开头的行,直接筛选出需要处理的目标数据。提取所有坐标组:对筛选后的行,用正则匹配所有
lat和lon对
正则示例:lat=(?<lat>\d{0,2}[.,]\d+).*?lon=(?<lon>\d{0,2}[.,]\d+)使用
Regex.Matches方法获取所有匹配项,遍历每个结果提取lat和lon值,再拼接成LineString格式(LINESTRING (lon1 lat1, lon2 lat2,...))。
方案2:单正则一次性匹配
用单个正则匹配前缀+所有坐标组,通过捕获集合获取所有匹配的坐标值:
正则示例:
^PREFIX(?<name>.*?)\(.*?(?:lat=(?<lat>\d{0,2}[.,]\d+).*?lon=(?<lon>\d{0,2}[.,]\d+))+
解释:
^PREFIX:确保行以指定前缀开头(?<name>.*?):可选的命名捕获组,提取前缀后的名称(如示例中的afkzh)(?:...):非捕获组包裹坐标对匹配规则,避免生成额外分组+:匹配一次或多次坐标对- 通过
Groups["lat"].Captures和Groups["lon"].Captures可获取所有纬度、经度的捕获结果
C#代码示例
using System; using System.Text.RegularExpressions; class Program { static void Main() { string input = "PREFIXafkzh(lat=34.42344, lon=23.6346jsdfkh,lat=2.4234, lon=12.124)"; string pattern = @"^PREFIX(?<name>.*?)\(.*?(?:lat=(?<lat>\d{0,2}[.,]\d+).*?lon=(?<lon>\d{0,2}[.,]\d+))+"; Match match = Regex.Match(input, pattern); if (match.Success) { // 提取名称属性 string name = match.Groups["name"].Value; Console.WriteLine($"名称:{name}"); // 获取所有坐标捕获结果 CaptureCollection latCaptures = match.Groups["lat"].Captures; CaptureCollection lonCaptures = match.Groups["lon"].Captures; // 拼接LineString格式(注意顺序为 经度 纬度) string lineString = "LINESTRING ("; for (int i = 0; i < latCaptures.Count; i++) { // 统一小数点格式为英文点号 string lon = lonCaptures[i].Value.Replace(',', '.'); string lat = latCaptures[i].Value.Replace(',', '.'); lineString += $"{lon} {lat}"; if (i != latCaptures.Count - 1) { lineString += ", "; } } lineString += ")"; Console.WriteLine($"LineString:{lineString}"); // 输出:LineString (23.6346 34.42344, 12.124 2.4234) } } }
注意事项
- 若前缀后有其他属性,可在正则中添加对应命名捕获组,灵活扩展提取逻辑
- 需统一处理小数点的逗号/点号格式,避免C#解析错误
- 若需跨行匹配,可添加
RegexOptions.Singleline参数
内容的提问来源于stack exchange,提问作者Jannik Michel
相关产品推荐
相关产品推荐

