подсчет строки со специальными символами в строке в С#

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

В сети я нашел следующую возможность, которая вполне работала ну пока. Однако,

count = Regex.Matches(_editor.Text, txtLookFor.Text, RegexOptions.IgnoreCase).Count;

Теперь я столкнулся с другой проблемой: я получаю следующую ошибку, когда считаю строку в формате «Nachricht erhalten (».

Сообщение об ошибке:

System.ArgumentException: "Nachricht erhalten (" проанализировано - недостаточно )-символов.


person Soeren3003    schedule 29.04.2020    source источник


Ответы (1)


Вам нужно экранировать символ (, так как он имеет специальную функцию в регулярных выражениях:

var test = Regex.Matches("Nachricht erhalten (3)", @"Nachricht erhalten \(", RegexOptions.IgnoreCase).Count;

Если вы делаете это с помощью пользовательского ввода, когда пользователь не знаком с регулярными выражениями, вам, вероятно, проще использовать IndexOf в цикле while, где вы продолжаете использовать новый индекс, найденный в последнем цикле. Что также может быть немного лучше по производительности, чем регулярное выражение. Пример:

var test = "This is a test";
var searchFor = "is";
var count = 0;
var index = test.IndexOf(searchFor, 0);
while (index != -1)
{
    ++count;
    index = test.IndexOf(searchFor, index + searchFor.Length);
} 
person 404    schedule 29.04.2020
comment
Есть ли другие персонажи, от которых мне нужно сбежать? Нравится - . › ? - person Soeren3003; 29.04.2020
comment
@ Soeren3003 См.: Какие символы необходимо экранировать в .NET Regex. ? вы можете просто использовать Regex.Escape - person Pac0; 29.04.2020
comment
if you do this by user input -› будьте осторожны, не следует выполнять произвольное регулярное выражение без предостережения (используйте тайм-аут или экземпляр). Это не только для простоты для пользователя, это также может быть уязвимостью (отказ в обслуживании, см. [meziantou.net/regex-deny-of-service-redos.htm] и найдите катастрофический возврат - person Pac0; 29.04.2020
comment
Спасибо за информацию и исходный код. Я сравнил их один раз и пришел к следующему результату: 00,0396874 сек Пока и 00,0039259 сек Регулярное выражение. Тем не менее, я решил использовать цикл while, потому что производительности достаточно для моего приложения. - person Soeren3003; 29.04.2020
comment
@ Soeren3003 правда. Это немного зависит от контекста. Регулярное выражение работает быстро для нескольких вхождений, но для больших файлов с большим количеством вхождений оно станет значительно медленнее из-за результирующих распределений (которые также быстро потребляют память). - person 404; 29.04.2020