简体   繁体   中英

Cross-line regex match in a Perl one-liner

My question sounds trivial, but I google many page still can't not find an answer.

I am on Windows. I have a text file. If I open it with Notepad++, it looks like this

在此处输入图片说明

I want to try several things

  1. delete all carriage return and line feed

    perl -i.bak -pe "s/\\r\\n//g" a.txt

surprisingly, there is nothing changed. What is wrong? But according to the doc , I am pretty sure \\r is CR and \\n is LF

  1. What I actually want to do is match across line. for example ^function.*\\r\\n! will match just like Notepad++ will does

在此处输入图片说明

If we want to indent the ! line if its previous line is started with "function", a naive thought would be (actually it works is notepad++)

perl -i.bak -pe "s/^(function.*\r\n)!/$1\t!/g" a.txt

But it didn't work. How to do it correctly?

By default, on Windows, CR+LF gets transformed to LF on read, and LF gets transformed to CR+LF on write. This makes lines look like they're LF-terminated regardless of the OS.


If sounds like you want to add a leading tab to lines starting with ! .

perl -i.bak -pe"s/^!/\t!/" a.txt
   -or-
perl -i.bak -pe"s/^(?=!)/\t/" a.txt

You might also be trying to avoid doing it on the first line.

perl -i.bak -pe"s/^!/\t!/ if $. > 1" a.txt
   -or-
perl -i.bak -pe"s/^(?=!)/\t/ if $. > 1" a.txt
  1. perl -i.bak -pe "s/\\n//" a.txt

Ie just change \\r\\n to \\n for the \\r\\n is automatically converted to \\n on Windows as it was explained by ikegami.


  1. perl -i.bak -0777 -pe "s/^(function.*?\\n)!/\\1\\t!/gm" a.txt

The main point here is that you need to read the entire file contents into a single string in order to do cross-line matches. -0777 parameter instructs Perl to do so (alternatively you may set $/ to an empty string from within Perl script).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM