регулярное выражение соответствует определенной строке без определенного завершающего символа

Ваш язык программирования

Такое поведение является артефактом библиотеки времени выполнения C и требованием языка программирования C. Другие языки программирования исторически были построены поверх библиотеки времени выполнения C и получили от нее такое поведение. Это справедливо, например, для программ на C++. Глава и стих языковых стандартов C и C++ довольно часто цитируются в Stack Overflow (q.v. ).

В частности, программы, написанные на Python, имеют такое же поведение, и о них довольно часто спрашивают, иногда обвиняя в поведении среду выполнения языка программирования -.

Инструменты для изменения поведения программ, использующих семантику языка по умолчанию (без изменения и перекомпиляции программ )представлены в двух формах :зависимой от языка -(и иногда библиотеки времени выполнения --специальные )инструменты, которые встраиваются в среду выполнения и изменяют буферизацию, а также инструменты, которые выполняют стандартный ввод-вывод в файлы, которые библиотеки среды выполнения определяют как интерактивные устройства. Инструменты последнего класса не зависят от языка -и включают Bernstein ptybandage.

Дополнительная литература

Несколько примеров вопроса о буферизации:

1
07.10.2020, 05:22
3 ответа

При использовании Perl-совместимых регулярных выражений (PCRE )добавление +после \s*приведет к жадному сопоставлению этих нулевых пробелов, предотвращая сопоставление [^+]с пробелами. Например. используя grepс -Pдля использования PCRE (параметр grep GNU ), а также -nдля отображения номеров строк:

grep -Pn 'CycleCounter\s*+[^+]' file

Другой PCRE:

grep -Pn 'CycleCounter(?!\s*\+)' file

На этот раз для указания not followed a '+' or some white space and a '+'используется отрицательный просмотр вперед.


Вы можете использовать sedдля удаления ненужных строк из вывода:

sed '/CycleCounter/!d; /CycleCounter[[:space:]]*+/d; =' file

Удалите все строки, не содержащие CycleCounter, а также удалите все строки, содержащие CycleCounter, за которыми следует любой пробел и «+». =для печати номеров строк.

1
18.03.2021, 22:59

Все дело в квантификаторе *.\s*-это означает, что совпадений может не быть, а второе выражение [^+] будет соответствовать пробельному символу сразу после слова CycleCounter.

grep 'CycleCounter\s\+[^+]'

или

grep 'CycleCounter\s*[^+]='

или

grep 'CycleCounter\s*[^+ ]'
1
18.03.2021, 22:59

Если вы хотите сопоставить CycleCounterпри условии, что это , а не , за которым следует необязательный пробел и +, вы можете использовать опережающий оператор perl -с отрицательным просмотром:

grep -P 'CycleCounter(?!\s*\+)'

(здесь предполагается grepреализация, которая поддерживает -Pдля perl -, например регулярные выражения ).

Если вы хотите сопоставить CycleCounter, если за ним следует необязательный пробел и символ, который не является ни +, ни пробелом:

grep 'CycleCounter[[:space:]]*[^+[:space:]]'

[[:space:]]является регулярным выражением POSIX, эквивалентным Perl's \s. Некоторые реализации grepтакже поддерживают \sв своих BRE/ERE как расширение, но не выражения внутри квадратных скобок, где [\s]требуется POSIX для соответствия либо \либо s.

В любом случае, хотя и [[:space:]], и \sбудут соответствовать символу новой строки, grepпо умолчанию работает с содержимым одной строки за раз (, не включая разделитель новой строки ), поэтому оба по-прежнему будут совпадать в первой строке:

   CycleCounter
     += 12;

, например.

С помощью pcregrep(, поставляемой с PCRE, библиотекой, которая реализует perl -подобно регулярным выражениям и используется большинством grepреализаций, поддерживающих -Pпараметр ), вы можете сделать:

pcregrep -M '(?s)CycleCounter(?!\s*\+).*?;'

Где -Mвключает многострочный режим -, а (?s)приводит к тому, что .также соответствует новой строке, а .*?;используется для проверки полного оператора C до следующего ;символа. печатается.

Конечно,его все еще можно обмануть такими вещами, как:

CycleCounter // blah ;
  += (c == ';')
  + 3;

Также обратите внимание, что они будут совпадать на MyCycleCounter2 += 3. Чтобы избежать этого, вы можете добавить операторы границы слов вокруг CycleCounter. В Perl это \bCycleCounter\b. Нет эквивалента регулярному выражению POSIX, хотя некоторые реализации grepтакже поддерживают \bили поддерживают \<CycleCounter\>или [[:<:]]CycleCounter[[:>:]]в качестве расширения.

1
18.03.2021, 22:59

Теги

Похожие вопросы