【发布时间】:2014-01-30 05:33:14
【问题描述】:
我正在尝试匹配天气报告中的某些天气(METAR 格式,如果有帮助的话)。要匹配的文本可以包含以下内容:
“RA”或“SN”或“TS”后跟“B”和两位或四位数字,或“E”和两位或四位数字,或两者,或多个“B”和“E”组(例如B05E20B45),导致类似“RAB05E20B45”的东西。这意味着“雨从 05 时开始,在 20 时结束,并在 45 时再次开始”。此外,在同一个字符串中可以有多个这样的结构(例如,“RAB05E20SNB25E55”=“雨从 05 开始,在 20 结束,然后下雪从 25 开始,在 55 结束”)。
以下是一些示例输入和我想获得的输出:
RAB05 RAB05
RAB05E15 RAB05E15
RAB05E15SNB25 RAB05E15 SNB05
RAB05E15SNB25E55 RAB05E15 SNB25E55
TSE01RAB05E15SNB25 TSE01 RAB05E15 SNB25
TSB01E55RAE15SNB25E55 TSB01E55 RAE15 SNB25E55
我很自大地认为下面会做到这一点......
((?:RA|SN|TS)(?:(?:B|E)(?:\d{2}|\d{4}))+)+
...但既然我在这里为此哭泣,显然没有。
这是我的测试代码(VB 2013):
Imports System.Text.RegularExpressions
Public Class Form1
Dim sItem As String = "TSB05E10RAB15"
Dim sPattern As String = "((?:RA|SN|TS)(?:(?:B|E)(?:\d{2}|\d{4}))+)+"
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
If Regex.Match(sItem, sPattern).Success Then
Dim rxMatches As GroupCollection = Regex.Match(sItem, sPattern, RegexOptions.IgnoreCase).Groups
'0th item is the entire match (e.g. TSB05E10RAB15)
'Succeeding elements are capture groups
For i = 1 To rxMatches.Count - 1
MessageBox.Show("Match #" & i & " = " & rxMatches(i).Value)
Next
End If
End Sub
End Class
我期望的结果是“TSB05E10”和“RAB15”,但我得到的只是“RAB15”。
我搜索了以下内容,但无济于事:
- Complex(?) Name Matching Regex for vBulletin
- Complex regex to split up a string
- Complex regex to split up a string - Part 2
如果有人愿意向我展示我的方式的错误......
编辑:
感谢所有提供帮助的人。这是可行的解决方案:
Imports System.Text.RegularExpressions
Public Class Form1
Dim sItem As String = "TSB05E10SHRAB10E15SNB25E35B45E55"
Dim sPattern As String = "(?:(?:SH)?(?:RA|SN)|TS)(?:(?:B|E)(?:\d{2}|\d{4}))+"
Dim rx As New Regex(sPattern, RegexOptions.IgnoreCase)
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim matches As MatchCollection = rx.Matches(sItem)
Label1.Text = "Input: " & sItem
For Each match As Match In matches
Dim groups As GroupCollection = match.Groups
ListBox1.Items.Add(groups.Item(0).Value)
Next
End Sub
End Class
【问题讨论】:
-
你的正则表达式matches all your examples。有什么问题?
-
我也觉得不错。 See it working here 我检查了全局复选框并使用了以下内容:((RA|SN|TS)((B|E)\d{2,4})+)
-
正如他们所说的那样,它可以工作,你能提供一个它应该工作但它不工作的样本吗?!
-
我相信第一列是数据,其余列是使用正则表达式解析出来的部分。
-
有没有理由用空格分割它然后解析单个元素不起作用?我想这会让你的代码更干净(更容易理解和维护)。正则表达式很酷,但有时它们会让人头疼,最好避免使用。