You need to enable JavaScript to run this app. Ruby中如何从user_location字段字符串提取lat、lon(正则或优解)
优惠活动
大模型
产品
解决方案
定价
更多

Ruby中如何从user_location字段字符串提取lat、lon(正则或优解)

Ruby 提取user_location中的经纬度

背景

数据库user_location列原设计存储标准JSON格式数据,正常示例为{"lon":74.46586,"lat":31.523199},但实际取出的字符串为Ruby Hash的inspect格式,示例为"{\"lon\"=>74.43935992994889, \"lat\"=>31.52203286189515}"。
现有提取逻辑依赖split拆分,鲁棒性差,需要更规范的实现方案。

现有实现

当前用到的提取代码:

lon = @session_request.user_location.split(',').first.split('=>').last.chomp('}').to_f
lat = @session_request.user_location.split(',').last.split('=>').last.chomp('}').to_f

Pry控制台验证结果:

  • 执行location = @session_request.user_location,返回:=> "{\"lon\"=>74.43935992994889, \"lat\"=>31.52203286189515}"
  • 执行提取lon的逻辑,返回:=> "74.43935992994889"
  • 执行提取lat的逻辑,返回:=> "31.52203286189515"

该方案依赖键的固定顺序,一旦键顺序调整、数值格式变化(如负数、科学计数法)就会出错,鲁棒性极差。

优化方案

1. 转标准JSON后解析(优先推荐)

现有字符串仅将标准JSON的键值分隔符:替换为了Ruby风格的=>,可以先替换分隔符再按标准JSON解析,安全且不依赖键顺序:

require 'json'
# 容错处理空值/解析失败的情况,与原逻辑行为兼容
location_str = @session_request.user_location.to_s
location_data = JSON.parse(location_str.gsub(/=>/, ':')) rescue {}

lon = location_data['lon'].to_f
lat = location_data['lat'].to_f

注意:不要直接使用eval解析该字符串,即使输入来自内部数据库,也存在潜在的代码注入风险。

2. 正则提取(轻量场景适用)

如果不需要完整解析整个结构,可直接用正则匹配指定键对应的数值,兼容正负值、科学计数法、多余空格等情况:

location_str = @session_request.user_location.to_s
# 匹配lon对应的数值,匹配不到默认返回0.0
lon = location_str.match(/"lon"\s*=>\s*(-?\d+\.?\d*(?:e[+-]?\d+)?)/i)&.[](1)&.to_f || 0.0
# 匹配lat对应的数值,匹配不到默认返回0.0
lat = location_str.match(/"lat"\s*=>\s*(-?\d+\.?\d*(?:e[+-]?\d+)?)/i)&.[](1)&.to_f || 0.0

3. 根源优化(长期方案)

当前字符串格式问题本质是写入时未做标准JSON序列化,长期可调整写入逻辑:

  • 写入数据时,不要直接用Hash的to_s方法转字符串,改用to_json生成标准JSON后再存储
  • 如果使用Rails框架,可直接将数据库列类型修改为json/jsonb,框架会自动完成序列化与反序列化,无需手动解析字符串。

内容的提问来源于stack exchange,提问作者Wasif Ali

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.22 08:54:03