Извлечение подстроки, когда строка для поиска имеет различные пробелы - PullRequest
0 голосов
/ 22 апреля 2020

У меня есть строка, как показано ниже.

Факс: 666-111-2222 Номер телефона: 200100200

Я хочу найти номер телефона. Но проблема в том, что количество пробелов после Phone и после # может варьироваться в разных строках для извлечения данных. Кроме того, написание сложной функции не рекомендуется, поскольку у меня есть большой набор данных для извлечения данных.

Я попробовал приведенный ниже код, и он дает мне правильный начальный индекс с n числом пробелов. Но я не могу найти позицию после: от этого

System.Globalization.CultureInfo.InvariantCulture.CompareInfo.IndexOf(FullString,"Phone#:",System.Globalization.CompareOptions.IgnoreSymbols)

Ответы [ 5 ]

1 голос
/ 22 апреля 2020

У вас есть пробел между Phone и #, также между # и:. Подстрока с одним параметром вернет строку из этого индекса в конец входной строки. Trim удалит все пробелы с любой стороны.

Private Function GetPhone(input As String) As String
    Dim i = input.IndexOf("Phone")
    Dim s = input.Substring(i)
    Dim splits = s.Split(":"c)
    Return splits(1).Trim
End Function

Я запустил функцию 10000 раз, и это заняло 5 миллисекунд.

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    Dim s = "Fax: 666-111-2222 Phone # : 200100200"
    Dim Phone As String = ""
    Dim sw As New Stopwatch
    sw.Start()
    For i = 0 To 10_000
        Phone = GetPhone(s)
    Next
    sw.Stop()
    Debug.Print(sw.ElapsedMilliseconds.ToString)
    MessageBox.Show(Phone)
End Sub
1 голос
/ 22 апреля 2020

Это явно работа для регулярных выражений.

String toMatch = "Fax : 666-111-2222 Phone # : 200100200";
Regex matchPhone = new Regex("\\bPhone\\s*#\\s*:\\s*");
MatchCollection matches = matchPhone.Matches(toMatch);
foreach (Match match in matches)
{
    Int32 position = match.Index + match.Length;
    // do whatever you want with the result here
}

В коде обратная косая черта удваивается, но фактическое регулярное выражение там:

\bPhone\s*#\s*:\s*

  • \b указывает границу слова, означающую начало или конец слова. Это также предотвращает сопоставление чего-либо вроде «МегаФона».
  • \s означает любой тип пробела. Это соответствует пробелам, символам табуляции и разрывам строк.
  • * означает ноль или более повторений, то есть не имеет значения, пропущены ли вообще пробелы или длина составляет сто пробелов, тем не менее,

Обратите внимание, что это даст вам только индекс для начала всех найденных телефонных номеров в данной строке. Вы не указали, существует ли какой-либо конкретный c способ определения конца телефонного номера, или даже если был какой-либо конкретный c ожидаемый формат для них, поэтому он не включен. Если вы хотите этого и не знаете точно, что может следовать за этим номером телефона, посмотрите на группы символов регулярного выражения и соответствующие спецификации c цифра c и используйте группу захвата, чтобы извлечь ее из сопоставленного содержимого.

Если во всей строке ожидается только одно совпадение, это можно сделать с помощью

String toMatch = "Fax : 666-111-2222 Phone # : 200100200";
Regex matchPhone = new Regex("\\bPhone\\s*#\\s*:\\s*");
Match match = matchPhone.Match(toMatch);
Int32 position = match.Index + match.Length;
0 голосов
/ 22 апреля 2020

Я думаю, вы должны регулярное выражение:

Regex rxPhone = new Regex(@"Phone\s*#\s*:\s*(\d+)");
Match match = rxPhone.Match(stringToMatch);
if (match.Success) //if the phone does not always exits
{
    string strPhoneNumber = match.Groups[1];
    int intPhoneNumber = int.Parse(match.Groups[1]);
    int position = match.Groups[1].Index
    //just pick the one you need
}
0 голосов
/ 22 апреля 2020

Если вы можете положиться на формат, то это довольно просто. Просто очистите строку всех пробелов (.Replace(" ", string.Empty)), а затем разделите символы, после которых начинается номер телефона, например, "#:":

var phoneFull = @"Fax : 666-111-2222 Phone # : 200100200";
var phone = phoneFull
    .Replace(" ", string.Empty)
    .Split("#:")
    .Last();
0 голосов
/ 22 апреля 2020

Я предполагаю, что вам нужен C# ответ.

Я бы использовал регулярные выражения, но если вы настаиваете на использовании IndexOf, вы можете сделать:

string fullString = "Fax : 666-111-2222 Phone # : 200100200";
int phonePos = fullString.IndexOf("Phone");
int hashPos = fullString.IndexOf("#", phonePos+"Phone".Length);
int colonPos = fullString.IndexOf(":", hashPos+1);

То Таким образом, у вас есть абсолютное положение двоеточия, независимо от того, сколько пробелов. Обратите внимание, что я использую String.IndexOf. Нет смысла выкапывать его из CompareInfo, как вы. Также обратите внимание, что я использую перегрузку, которая принимает дополнительный параметр, который является начальным индексом.

...