Сведения о вопросе

Ислам

16:03, 1st July, 2020

Теги

regex   ansi    

Почему это регулярное выражение быстрее?

Просмотров: 465   Ответов: 4

Я пишу своего рода клиент Telnet в C#, и часть того, что мне нужно разобрать, - это escape-последовательности ANSI/VT100, в частности, только те, которые используются для цвета и форматирования (подробно здесь ).

Один из методов, который у меня есть, - это найти все коды и удалить их, чтобы я мог отображать текст без форматирования, если это необходимо:

    
public static string StripStringFormating(string formattedString)
{
    if (rTest.IsMatch(formattedString))
        return rTest.Replace(formattedString, string.Empty);
    else
        return formattedString;
}

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

static Regex rText = new Regex(@"\e\[[\d;]+m", RegexOptions.Compiled);

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

static Regex rTest = 
              new Regex(@"(\e(\[([\d;]*[mz]?))?)?", RegexOptions.Compiled);

Это не только сработало, но и было на самом деле быстрее и уменьшило влияние на мой текстовый рендеринг. Может кто-нибудь объяснить новичку regexp, почему? :)



  Сведения об ответе

+-*/

18:03, 1st July, 2020

Вы действительно хотите запустить регулярное выражение дважды? Не проверив (плохой я) я бы подумал, что это будет хорошо работать:

public static string StripStringFormating(string formattedString)
{    
    return rTest.Replace(formattedString, string.Empty);
}

Если это так, вы должны увидеть, что он работает ~twice так же быстро...


  Сведения об ответе

+-*/

18:03, 1st July, 2020

Причина, по которой #1 медленнее, заключается в том, что [\d;]+ является жадным квантором. Используя +? или *? собирается сделать ленивую количественную оценку. Дополнительную информацию смотрите в разделе MSDN-кванторы .

Возможно, вы захотите попробовать:

"(\e\[(\d{1,2};)*?[mz]?)?"

Это может быть быстрее для вас.


  Сведения об ответе

piter

18:03, 1st July, 2020

Не делая детального анализа, я бы предположил, что это быстрее из-за вопросительных знаков. Они позволяют регулярному выражению быть "lazy," и останавливаться, как только у них будет достаточно совпадений, а не проверять, совпадает ли rest входных данных.

Однако я не совсем доволен этим ответом, потому что это в основном относится к вопросительным знакам после * или +. Если бы я был более знаком с вводными данными, это могло бы иметь для меня больше смысла.

(Кроме того, для форматирования кода Вы можете выбрать весь код и нажать Ctrl + K , чтобы добавить четыре необходимых пробела.)


  Сведения об ответе

ASSembler

18:03, 1st July, 2020

Я не уверен, что это поможет в том, над чем вы работаете, но давным-давно я написал регулярное выражение для разбора графических файлов ANSI.

(?s)(?:\e\[(?:(\d+);?)*([A-Za-z])(.*?))(?=\e\[|\z)

Он будет возвращать каждый код и связанный с ним текст.

Входная строка:

<ESC>[1;32mThis is bright green.<ESC>[0m This is the default color.

Результаты:

[ [1, 32], m, This is bright green.]
[0, m, This is the default color.]


Ответить на вопрос

Чтобы ответить на вопрос вам нужно войти в систему или зарегистрироваться