что это регулярные выражения пытаются сопоставить в TCL - PullRequest
0 голосов
/ 12 марта 2012

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

set result [regexp "$PersonName\\|\[^\\n]*\\|\[^\\n]*\\|\\s*0x$PersonId\\|\\s*$gender" [split $outPut \n]]

, что регулярные выражения выше пытаются сопоставить?значение результата?

Ответы [ 2 ]

2 голосов
/ 12 марта 2012

Сложность в том, что спецификация регулярного выражения защищена от правил интерполяции строк Tcl.

Чтобы распутаться, вы должны подумать так:

  1. "$PersonName\\|\[^\\n]*\\|\[^\\n]*\\|\\s*0x$PersonId\\|\\s*$gender" - строка в двойных кавычках, поэтому применяются обычные правила интерполяции:

    • Каждый обратный слеш экранируется следующим символом;
    • Каждая ссылка $variable заменяется на ее значение;
    • [command ...] заменяет строку, возвращаемую выполненным command.

    Таким образом, в каждом случае \\ создается единственный символ '\' в интерполированной строке, а \[ предназначены для предотвращения интерпретации Tcl этих [^\n] как команд (называемых «^ \ n»). быть исполненным.

    Таким образом, если мы предположим, что переменная PersonName содержит "Joe", PersonId содержит DEAD и gender содержит "male", Tcl получит Joe\|[^\n]*\|[^\n]*\|\s*0xDEAD\|\s*male после выполнения всех подстановок в исходной строке.

  2. Теперь результирующая строка передается механизму RE, который применяет свои собственные правила синтаксиса при синтаксическом анализе строки, обозначающей регулярное выражение, как описано в re_syntax справочной странице .

    В соответствии с этими правилами каждая обратная косая черта, опять же, экранируется от следующего символа, если только это не специальная «escape-запись при вводе символа», поэтому здесь мы имеем:

    • \s обозначает «любой символ пробела»;
    • \| экранирует «|» заставить его потерять свое обычное значение & mdash; ввести изменение & mdash; так, чтобы оно буквально совпадало с символом '|'.

    Конструкция [^\n]* означает «самую длинную серию из нуля или более символов, не включая символ новой строки». Читайте о "классах персонажей" в регулярных выражениях для получения дополнительной информации.

0 голосов
/ 13 марта 2012

Значение result будет количеством совпадений регулярного выражения.В отсутствие опции -all это всегда будет 0 или 1 (т.е. не найден / найден).

В целом, это регулярное выражение (которое хорошо объясняет ответ @ kostix) действительно ужасно, хотя,RE являются мощным инструментом, но их очень легко спутать с ними.Более того, если вы разбиваете вывод на новые строки, вам не нужно пытаться исключить их в совпадении RE;в этом случае определенно не будет новых строк в результате split.

Если бы мы лучше поняли, что вы пытаетесь сделать, мы могли бы направить вас к гораздо более эффективным методамсопоставление (например, использование lsearch с подходящими параметрами, загрузка данных в базу данных SQLite в памяти).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...