【问题标题】:Regex for well-known text知名文本的正则表达式
【发布时间】:2014-03-12 15:22:53
【问题描述】:

我正在寻找正则表达式来验证和解析众所周知的文本,这是一种用于传输空间数据的格式,如下所示:

POLYGON((51.124 -3.973, 51.1 -3.012, ....))

MULTIPOLYGON(((POLYGON((51.124 -3.973, 51.1 -3.012, ....)),POLYGON((50.14 -13.973, 51.1 -13.012, ....))

在其他变体中。

这里有一个很好的答案:Parsing a WKT-file 使用正则表达式:

\d+(?:\.\d*)?

从其他地方我也看到了

\d*\.\d+|\d+

(\d*\.)?\d+

这些似乎都做同样的事情,但这让我想知道这 3 个正则表达式的相对工作原理,以及是否有任何性能问题或需要注意的细微之处。

明确地说,我知道有用于解析各种语言的 WKT 的库。我的问题纯粹是关于数字提取正则表达式的相对行为。

【问题讨论】:

  • 你已经知道正则表达式了吗?也就是说,您对帖子中每个正则表达式的不同部分有基本的了解?
  • 是的,我理解匹配组和非匹配组的概念,各种量词的含义等,但我觉得我缺少更深层次的东西。

标签: regex wkt


【解决方案1】:

这取决于您需要允许的数字格式,例如:

格式 1:22 格式 2:22.2 格式 3:.2 格式 4:2。
  • 第一个模式 \d+(?:\.\d*)? 匹配 1,2,4
  • 第二个模式 \d*\.\d+|\d+ 匹配 1,2,3
  • 第三个模式 (\d*\.)?\d+ 匹配 1,2,3(并且有一个不需要的捕获组)

注意:如果数字是整数,模式 2 和 3 的成功速度比第一个慢,因为它们必须匹配直到点的所有数字,回溯到开始并重试相同的数字更多时间。 (参见下面的架构)

字符串 |图案 |状态 -----+----------------+---------------------------- -- 123 | \d*\.\d+|\d+ |开始 123 | \d*\.\d+|\d+ |好的 123 | \d*\.\d+|\d+ |好的 123 | \d*\.\d+|\d+ |好的 123 | \d*\.\d+|\d+ |失败 => 回溯 123 | \d*\.\d+|\d+ |失败 => 回溯 123 | \d*\.\d+|\d+ |失败 => 回溯 123 | \d*\.\d+|\d+ |转到下一个选项 123 | \d*\.\d+|\d+ |好的 123 | \d*\.\d+|\d+ |好的 123 | \d*\.\d+|\d+ |好的 => 成功

如果要匹配四种情况,可以使用:

\.\d+|\d+(?:\.\d*)?

(+) 如果数字不以点开头,则第一个替代方案立即失败,第二个替代方案将匹配所有其他情况。回溯被限制在最低限度。
(-) 如果您的数字很少以点开头,则第一个替代方案将被测试并且每次都会失败。然而,第一种选择很快就失败了。(换句话说,出于同样的原因)。在这种情况下,最好使用\d+(?:\.\d*)?|\.\d+

显然,如果要支持负值,则需要添加-?

-?(?:\.\d+|\d+(?:\.\d*)?)

【讨论】:

  • 谢谢,这正是我所希望的答案。
  • WKT 数据可能非常大,因此速度很重要。但是,纬度/经度数据可以这样表示,首先,伦敦处于数字可能以点开头的区域,虽然我只看到它为 0.xxx,但绝对值得考虑。
  • @JohnBarça:在这种情况下0.xxx 第一个模式\d+(\.\d*)? 是迄今为止最好的。
  • 可以将最终模式简化为 -?(?:\d*(?:\.\d*)?) 还是有特定原因我们将前导数字匹配分成单独的字符类匹配?
  • @JLunda:不,因为您的模式匹配空字符串或-.-.。其他模式确保至少一位数。
猜你喜欢
  • 2017-08-24
  • 2013-05-30
  • 2022-08-19
  • 2022-12-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多