#vb.net #pattern-matching
#vb.net #сопоставление с образцом
Вопрос:
У меня есть введенная пользователем строка:
"{0.3064, 15.6497, 60.7668, 52.1362, 76.6645, 97, -15.8315, -6.8806, 5.547, -2.3381, -23.9905, 40.4569, 60.1592, 27.1418, 42.9375, -22.8297, -11.7423, -17.1576, -33.9918, 7.0585}"
и я хотел бы иметь возможность проверить его на основе наличия «{» в начале, «}» в конце и двадцати чисел, разделенных запятыми, от -1000 до 1000 между запятыми.
Я пытался использовать оператор like, как показано ниже, но безуспешно. Все возвращает False независимо от того, соответствует ли оно шаблону или нет. Как я могу проверить на основе этого шаблона.
Это то, что я уже пробовал:
ArrayOk = ArrayValues1txt.Text Like "{[(1000)-1000],[(1000)-1000],[(1000)-1000],[(1000)-1000],[(1000)-1000],[(1000)-1000],[(1000)-1000],[(1000)-1000],[(1000)-1000],[(1000)-1000],[(1000)-1000],[(1000)-1000],[(1000)-1000],[(1000)-1000],[(1000)-1000],[(1000)-1000],[(1000)-1000],[(1000)-1000],[(1000)-1000],[(1000)-1000]}"
If ArrayOk = False Then
MsgBox("Wrong array pattern! Pattern must contain 20 elements and be in the form {#,#}",
MessageBoxButtons.OK, "Bad Array Entered")
GoTo Canceller
Else
End If
Ответ №1:
Вы можете использовать регулярное выражение для проверки общего шаблона: есть ли 20 десятичных значений, разделенных запятыми, заключенными в фигурные скобки?
Dim pattern = "^{((-?d (.d )?),s?){19}(-?d (.d )?)}$"
Dim input = "{0.3064, 15.6497, 60.7668, 52.1362, 76.6645, 97, -15.8315, -6.8806, 5.547, -2.3381, -23.9905, 40.4569, 60.1592, 27.1418, 42.9375, -22.8297, -11.7423, -17.1576, -33.9918, 7.0585}"
If (Regex.IsMatch(input, pattern)) Then
End If
После того как вы убедились, что он соответствует определенному шаблону, вы можете проверить, что числа соответствуют проверке числового диапазона, выполнив следующие действия:
- Удалите скобки из строки
- Разделите строку запятой
- Обрежьте все лишние пробелы в элементах
- Преобразуйте элементы в дробные значения (двойные, десятичные и т.д.).
- Проверьте, находятся ли товары в пределах досягаемости
Вы можете выполнить многие из этих шагов с помощью LINQ, что сделает его намного более кратким:
Dim pattern = "^{((-?d (.d )?),s?){19}(-?d (.d )?)}$"
Dim input = "{0.3064, 15.6497, 60.7668, 52.1362, 76.6645, 97, -15.8315, -6.8806, 5.547, -2.3381, -23.9905, 40.4569, 60.1592, 27.1418, 42.9375, -22.8297, -11.7423, -17.1576, -33.9918, 7.0585}"
If (Regex.IsMatch(input, pattern)) Then
input = input.Replace("{", String.Empty).Replace("}", String.Empty)
Dim items = input.Split(",")
Dim convertedItems = items.Select(Function(item) Convert.ToDouble(item.Trim())).ToArray()
If (convertedItems.All(Function(item) item >= -1000 AndAlso item <= 1000)) Then
Console.WriteLine("All of the items are within -1000 and 1000")
End If
End If
Вот живая демонстрация: fiddle
Ответ №2:
Я использовал String.StartsWith
и String.EndsWith
для проверки наличия брекетов. Затем я отрубил их с Substring
помощью . Затем я разделяю строку запятыми. Я проверил, было ли там ровно 20 элементов.
Если мы зайдем так далеко, я пройдусь по каждому элементу. Обрежьте все начальные или конечные пробелы и замените их на двойные. Тогда я смогу провести сравнение чисел.
Private Function ValidateArray(input As String) As Boolean
If Not input.StartsWith("{") OrElse Not input.EndsWith("}") Then
Return False
End If
input = input.Substring(1, input.Length - 2)
Dim splits = input.Split(","c)
If splits.Length <> 20 Then
Return False
End If
For Each n In splits
Dim dbl = CDbl(n.Trim)
If dbl > 1000 OrElse dbl < -1000 Then
Return False
End If
Next
Return True
End Function
Использование:
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Dim IsValid = ValidateArray("{0.3064, 15.6497, 60.7668, 52.1362, 76.6645, 97, -15.8315, -6.8806, 5.547, -2.3381, -23.9905, 40.4569, 60.1592, 27.1418, 42.9375, -22.8297, -11.7423, -17.1576, -33.9918, 7.0585}")
MessageBox.Show(IsValid.ToString)
End Sub