C # Regex.Split: удаление пустых результатов - PullRequest
29 голосов
/ 06 февраля 2011

Я работаю над приложением, которое импортирует тысячи строк, где каждая строка имеет следующий формат:

|* 9070183020  |04.02.2011    |107222     |M/S SUNNY MEDICOS                  |GHAZIABAD                          |      32,768.00 |

Я использую следующие Regex, чтобы разбить строки на нужные мне данные:

Regex lineSplitter = new Regex(@"(?:^\|\*|\|)\s*(.*?)\s+(?=\|)");
string[] columns = lineSplitter.Split(data);

foreach (string c in columns)
    Console.Write("[" + c + "] ");

Это дает мне следующий результат:

[] [9070183020] [] [04.02.2011] [] [107222] [] [M/S SUNNY MEDICOS] [] [GHAZIABAD] [] [32,768.00] [|]

Теперь у меня два вопроса. 1.Как удалить пустые результаты. Я знаю, что могу использовать:

string[] columns = lineSplitter.Split(data).Where(s => !string.IsNullOrEmpty(s)).ToArray();

, но есть ли какой-нибудь встроенный метод для удаления пустых результатов? 2.Как я могу удалить последнюю трубу? Спасибо за любую помощь.С Уважением,Йогеш.

РЕДАКТИРОВАТЬ: Я думаю, что мой вопрос был немного неправильно понят.Это никогда не было о , как я могу это сделать .Это было примерно , как я могу сделать это, изменив Regex в приведенном выше коде .

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

Regex regex = new Regex(@"(^\|\*\s*)|(\s*\|\s*)");
data = regex.Replace(data, "|");

string[] columns = data.Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries);

Во-вторых, в качестве тестового примера, моя системаможет проанализировать 92k + ​​таких строк менее чем за 1,5 секунды в исходном методе и менее чем за 700 миллисекунд во втором методе, где я никогда не найду более пары тысяч в реальных случаях, поэтому я не думаю, что мне нужно думатьо скорости здесь.По моему мнению, думать о скорости в этом случае - преждевременная оптимизация.

Я нашел ответ на свой первый вопрос: это невозможно сделать с помощью Split, поскольку такой опции нет.

Все еще ищу ответ на мой второй вопрос.

Ответы [ 9 ]

42 голосов
/ 06 февраля 2011
Regex lineSplitter = new Regex(@"[\s*\*]*\|[\s*\*]*");
var columns = lineSplitter.Split(data).Where(s => s != String.Empty);

или вы можете просто сделать:

string[] columns = data.Split(new char[] {'|'}, StringSplitOptions.RemoveEmptyEntries);
foreach (string c in columns) this.textBox1.Text += "[" + c.Trim(' ', '*') + "] " + "\r\n";

И нет, нет возможности удалить пустые записи для RegEx.Split, как для String.Split.также можно использовать спички.

2 голосов
/ 12 августа 2015

Я думаю, что это может работать как эквивалент удаления пустых строк:

string[] splitter = Regex.Split(textvalue,@"\s").Where(s => s != String.Empty).ToArray<string>();
1 голос
/ 06 февраля 2011

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

Поэтому используйте что-то вроде:

const Char[] splitChars = new Char[] {'|'};

string[] splitData = data.Split(splitChars, StringSplitOptions.RemoveEmptyEntries)
1 голос
/ 06 февраля 2011

В качестве альтернативы расщеплению, которое всегда будет вызывать проблемы, когда ваши разделители также присутствуют в начале и конце ввода, вы можете попробовать сопоставить содержимое в каналах:

foreach (var token in Regex.Matches(input, @"\|\*?\s*(\S[^|]*?)\s*(?=\|)"))
{
    Console.WriteLine("[{0}]", token.Groups[1].Value);
}

// Prints the following:
// [9070183020]
// [04.02.2011]
// [107222]
// [M/S SUNNY MEDICOS]
// [GHAZIABAD]
// [32,768.00]
0 голосов
/ 16 декабря 2017

используйте это решение:

string stringwithDelemeterNoEmptyValues= string.Join(",", stringwithDelemeterWithEmptyValues.Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries));
0 голосов
/ 02 июля 2017

1.Как удалить пустые результаты?

Вы можете использовать LINQ для удаления всех записей, равных string.Empty :

string[] columns = lineSplitter.Split(data); 
columns = columns.ToList().RemoveAll(c => c.Equals(string.Empty)).ToArray();

2.Как я могу удалить последний канал?

Вы можете использовать LINQ здесь, чтобы удалить все записи, равные символу, который вы хотите удалить:

columns = columns.ToList().RemoveAll(c => c.Equals("|")).ToArray();
0 голосов
/ 02 июля 2017

Основываясь на замечательном ответе @Jaroslav Jandek, я написал extension method, я поставил это здесь, возможно, это может сэкономить ваше время.

/// <summary>
/// String.Split with RemoveEmptyEntries option for clean up empty entries from result
/// </summary>
/// <param name="s">Value to parse</param>
/// <param name="separator">The separator</param>
/// <param name="index">Hint: pass -1 to get Last item</param>
/// <param name="wholeResult">Get array of split value</param>
/// <returns></returns>
public static object CleanSplit(this string s, char separator, int index, bool wholeResult = false)
{
    if (string.IsNullOrWhiteSpace(s)) return "";

    var split = s.Split(new char[] { separator }, StringSplitOptions.RemoveEmptyEntries);

    if (wholeResult) return split;

    if (index == -1) return split.Last();

    if (split[index] != null) return split[index];

    return "";
}
0 голосов
/ 06 февраля 2011

У меня может быть неправильное представление, но вы просто хотите разделить строку data, используя '|'символ как разделитель?В этом случае вы могли бы попробовать:

string[] result = data.Split(new[] { "|" }, StringSplitOptions.RemoveEmptyEntries).Select(d => d.Trim()).ToArray();

Это вернет все поля без пробелов и с удаленными пустыми полями.Вы можете, что вам нравится, в части Select, чтобы отформатировать результаты, например

.Select(d => "[" + d.Trim() + "]").ToArray();
0 голосов
/ 06 февраля 2011

Как насчет этого:

при условии, что у нас есть строка:

line1="|* 9070183020  |04.02.2011    |107222     |M/S SUNNY MEDICOS                  |GHAZIABAD                          |      32,768.00 |";

мы можем получить требуемый результат как:

string[] columns =Regex.Split(line1,"|");
foreach (string c in columns)
         c=c.Replace("*","").Trim();

Это даст следующий результат:

[9070183020] [04.02.2011] [107222] [M/S SUNNY MEDICOS] [GHAZIABAD] [32,768.00]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...