perl替换功能备忘录

Perl 替换字符串

一. 介绍使用

s/regex/replacement/modifiers

进行查找替换

二. 实例
(1) s///
(2) s///r
用它进行匹配后,原始标量的值不会发生变化,可以把新值赋值给一个新的标量
(3) s///g 多次查找替换
(4) s///e 求值
(5) 如果 regex 里有 / 斜线这样的特殊符号,可以使用如下的定界符
s/// 可以用 s!!! , s{}{} , s{}// 进行替换,m#…# 或 s|…|…| 也都可以。

《Perl语言入门》一书中第八章开篇就有讲到,可以选择任何成对的定界符: m(fred)、m、m{fred}、m[fred]
也可以用其他不成对的定界符:m,fred,、m|fred|、m^fred^等等

不成对定界符就是没有左右之分的符号,所以模式两边使用同样的标点符号。

比如之前提写的使用 perl 去掉 utf-8 文件的 bom 头

grep -rl $'\xEF\xBB\xBF' . | xargs perl -i -pe 's{\xEF\xBB\xBF}{}'

模式定界符为斜线 /,但其可用字母m自行指定,如:

m!/u/iqpublic/perl/prog1! 等价于 /\/u\/jqpublic\/perl\/prog1/

当用字符’作为定界符时,不做变量替换;当用特殊字符作为定界符时,其转义功能或特殊功能即不能使用。成对的符号必须成对的使用。

perl 中通常使用 / 斜线或者 {} 花括号来作为定界符,在 IDE 中,一般都具有从左括号跳到相应的右括号的功能,在维护代码中要快速移动光标时就非常方便。
比如:
IntelliJ IDEA 快捷键
Ctrl+[ OR ] 可以跑到大括号的开头与结尾
ctrl+shift+m 移动到括号外面

打了左括号之后,自动出现一对括号,并在右边的括号后面出现一个切换点,输入完之后按一下Tab键就跳到右边括号的外边了
IntelliJ IDEA 可以使用 tab 键跳出括号和引号吗?
2018.2 EAP version 中,官方加入了新的特性,默认关闭,需要自行开启:在 Settings->Editor->General->Smart Keys 中就能找到 Jump outside closing bracket/quote with Tab 点击即可。

替换操作符的选项(modifiers )如下表:
选项 描述
g 改变模式中的所有匹配
i 忽略模式中的大小写
e 替换字符串作为表达式
m 将待匹配串视为多行
o 仅赋值一次
s 将待匹配串视为单行
x 忽略模式中的空白


关于Perl正则的一些规范,很多妙用。

1,定界符

    =~ m/there/;
    =~ s/there/here/;

还有其它的定界符:

    =~ /there/
    =~ m#there#;
    =~ s#there#here#;

    =~ m(there);
    =~ s(there)(here);

    =~ m{there};
    =~ s{there}{here};

    =~ m[there];
    =~ s[there][here];

    =~ m,there,;
    =~ s,there,here,;

    =~ m.there.;
    =~ s.there.here.;

    =~ m|there|;
    =~ s|there|here|;

    =~ m'there';
    =~ s'there'here';

2,修改符
修改符一般放在语句最后一个正斜杠(或者其他分隔符)的后面,修改符还可在匹配范式内定义,这是用(? 修改符)来实现的。
/x 允许在范式中加上注释和额外的空白字符,以提高程序的可读性。
/i 允许不分大小写的匹配范式。
/s 单行方式,决定了圆点 . 是否匹配换行符,使用了/s,圆点就匹配换行符,否则就不匹配。
比如:

#!/usr/bin/perl

use strict;
use warnings;

my $string = ".\n.";
print "The original string is: $string\n";

my $num = $string =~ s|(.)|#|sg;
print "$num occurences change, and be changed to: $string\n";

exit;

/m 多行方式,决定了脱字号 ^ 和美圆符 $ 是否匹配换行符,如果不用/s,^和$只能定位在字串的开始和结束处,它们并不匹配嵌入的换行符,这种情况等同于\A和\Z,否则不仅仅匹配字串的开始和结束,也匹配刚好处在嵌入换行符前后的一个位置。
/o 仅仅一次计算表达式的值
/e 将替代字符串作为一个表达式(仅仅在替代操作时有效)
/g 是一个全局修改符。另外,/g与while使用能在字串的所有匹配中进行遍历。
修改符 /G 必须与 /g 一起使用,用来匹配前一个 /g 匹配的停止位置。
如

#!/usr/bin/perl

use strict;
use warnings;

my $string = "~32sda13dAZ.'sDa#!3_C-!";
print "The original string is: $string\n";

my $num = $string =~ s.\w.#.g;
print "$num occurences change, and be changed to: $string\n";

exit;

3,正则里一些特殊字符
() 将表达式结组
[] 寻找一组字符
\d 等于 [0-9]
\D 等于 [^0-9]
\w 等于 [0-9A-Za-z_]
\W 等于 [^0-9A-Za-z_]
\s 等于 [\f\n\r\t ]
\S 等于 [^\f\n\r\t ]
. 等于 [^\n]

4,关于一些特殊符号
\b 不属于空白字符,向前缩进一个字符
\t 属于空白字符,匹配制表符
\r 属于空白字符,匹配回车符
\a 不属于空白字符,匹配闹钟符
\e 不属于空白字符,匹配转义符
\033 不属于空白字符,匹配八进制符
\x1B 不属于空白字符,匹配十六进制符
\c[ 不属于空白字符,匹配控制字符
属于空白字符,匹配空格
属于空白字符,匹配制表符
\f 属于空白字符,匹配换页符
\n 属于空白字符,匹配换行符
\0 不属于空白字符,功能不详
\c 不属于空白字符,功能不详
\x 不属于空白字符,功能不详

5,注意正则里的选择符的特殊性
选择运算符是所有运算符中优先级最低的,这意味着它最后执行。

6,正则里的限定符的一些经典用法
限定符常常与一些字符或词联合使用
* 匹配任意数个;
+ 匹配一个或多个;
? 匹配零个或一个;
{n} 匹配 n 个;
{n,m} 匹配 n 至 m 个;
{n,} 匹配 n 和 n 个以上;

限定符贪婪好像与生俱有的。在缺省状态下,*或+限定符匹配满足正则表达式的一个范式的最大实例数。可用?号显式的规定限定符的不贪婪。如果问号放在另一个限制符之后(甚至另一个问号之后),都可以使限定符不贪婪。

7,声明与断言
首先注意声明的长度为 0;
Perl种有一组控制大小写和换码的声明:
\u 使下一个字母变大写;
\l 使下一个字母变小写;
\U 使文本的剩余字符变成大写;
\L 使文本的剩余字符变成小写;
\Q 会除字母之外的其他字符进行换码处理,直至遇到 \E 声明、常规表达式结束或者字串结束。
\A声明和脱字符号(^)匹配字串的开始;
\Z声明和美元符号($)匹配字串的结束或刚好在字串结束前的换行符;
\z 只匹配字串的结束;
\b 匹配一个单词(字)边界;
\B 匹配一个非单词(字)边界;

(?#text) 忽略括号内的注释文本;
(?:pattern) 与组一致,但匹配时不生成$1,$2;
(?imsx:pattern) 与组一致,但匹配时不生成$1,$2,在特定的风格有效期间,内嵌风格匹配修饰符,等价于/pattern/option; 其中 option 为 i m s x;
(?=pattern) 前看声明,如果正则表达式在下一次匹配 pattern 风格,就开始匹配,而且不影响匹配效果。如/\w+(?=\t)/将匹配制表符是否恰好在一个字\w+后面出现,并且制表符不添加到$&的值中;
(?!pattern) 如果正则表达式在后面不匹配 pattern ,才会开始匹配。如/foo(?!bar)/,只有当出现 foo,并且后面不出现 bar 时才开始匹配;
(?<=pattern) 后看声明,只有在pattern已经匹配下面的表达式,并且不将 pattern 的结果放入$&变量中,才匹配下面的语句。如/(?<=\t)\W+/匹配制表符是否恰好在\W+前出现,但又不将制表符送到$&中;
(? (?{code}) 表示对 code 的使用是试验性的。如果返回真,就认为是与(?:pattern)断言同一行里的匹配。code 不插入变量。这个断言仅仅在 use re 'eval' 编译指示符时才有效;
(?>pattern) 如果类型锁定在当前位置,就使用单独的 pattern 匹配子字符串。如正则表达式/^(?>a*)ab/永远不会匹配,因为语句(?>a*)将匹配字符串开头所有的 a 字符,并删除与 ab 匹配的字符 a;
(!<=pattern) 非后看声明,与后看声明意思相反;
(!=pattern) 非前看声明,与前看声明意思相反;
(?(condition)yes-pattern|no-pattern) 条件表达式——条件语句或者是一个圆括号中的整数,或者是一个断言;
(?(condition)yes-pattern)
(?imsx) 嵌入风格匹配修饰符。当要把表达式修改符嵌入在变量中,然后把变量用在不指定自己的修饰符的一般规则表达式中;
(?-imsx) 这个断言很有用——后面带任何内容都会关闭修饰符,直到出现另一个嵌入的修饰符。

8,向后引用
Perl的正则表达式引擎允许使用前面匹配好的值,这些值叫做向后引用。
例如:

    =~ m/(\w)\W*(\w)\W*(\w)\W*(\w)\W*\4\W*\3\W*\2\W*\1/;
    =~ s/(\w)\W*(\w)\W*(\w)\W*(\w)/$4$3$2$1/;

原文地址:http://my.huhoo.net/archives/2006/04/perl.html

Linux下utf-8 BOM 文件的检查与删除

当源程序是 gbk 格式,你转换为 utf8 的时候,很多情况是头部会出现 bom,如果是 php 代码,这样会出现很多意想不到的事情,那怎么办呢,你可以用 linux 命令来查找,然后对文件的 bom 进行删除。

grep -r $'\xef\xbb\xbf' * |grep .php

bom:UTF-8签名(UTF-8 signature)也叫做BOM(Byte Order Mark)

查询BOM:

:set bomb?

用 vim 去掉 utf-8 BOM

:set nobomb

保留 utf-8 BOM

:set bomb

vim 转换文件为 unix 格式

:set ff=unix

使用 grep 查找带 bom 的文件,并使用 perl 去掉 bom 头

grep -rl $'\xEF\xBB\xBF' . | xargs perl -i -pe 's{\xEF\xBB\xBF}{}'

[转载]功能丰富的 Perl: 一行程序 101

Perl 作为命令行实用程序
Teodor Zlatanov (tzz@iglou.com), 程序员, Gold Software Systems
简介: 那些将 Perl 用作编程语言的人经常忽视了:Perl 用作命令行操作的快速而又难看的脚本编制引擎时是很有用的。通过命令行,Perl 仅用一行就可以实现大多数其它语言需要数页代码才能完成的任务。跟着 Teodor,他会教给您一些有用的示例。

为了完成这一篇 how-to 文章,您需要在系统上安装 Perl 5.6.0。您的系统最好安装比较新(2000 或更新)的 Linux 或 Unix,但是其它操作系统也能照样工作。所有的示例都使用 tcsh shell(尽管 bash 及其它 shell 也能工作)。虽然这些示例也许可以和较早版本的 Perl、Linux 及其它操作系统一起工作,但是如果它们不能一起工作,那么它们无法工作的原因可以作为练习,让读者去解决。

我想说的第一点是:有经验的程序员不应回避快速而又难看的解决方案。在其它专栏文章中,我已经强调了文档编制和彻底性。本专栏文章将集中在编程的消极面,其中文档编制是可选的,而咖啡因却无从选择。因为我们已经身陷其中。

第二点和第一点一样重要:快速而又难看的解决方案很难正确完成。如果您知道如何记录、测试和调试完整的脚本,那么您就 非常有可能在一行程序中取得成功。如果您不知道怎样做,那么这就像是企图用鲱鱼来砍倒红杉树(而您的技能就是那条鲱鱼)。

第一步,您应该学习 shell 的特性:Unix 将命令行参数传递给 Perl 的方式及这些参数的 Perl 解释方法。

命令行的实质

在 Unix 中您将看到可执行任务的概念,一个进程通常是装入内存的程序。除了初始进程外,进程都可以由其它进程来启动,初始进程通常是由内核(有时由内核进程)来启动的。就用户的观点而言,启动进程需要 shell 或启动程序。因此,当用户在 shell 命令行输入“xeyes”或者从启动程序菜单(类似于 GNOME 任务栏)选择 X Eyes 应用程序时,shell 或启动程序创建新的进程以运行该程序。

进程获得命令行参数。因此,例如,“perl”和“perl -w”是对同一个程序的两种不同调用。在内部,Perl(类似于 C)将参数传递给它用 @ARGV 数组解释的脚本。但是和 C 不同的是,Perl 偷偷地从脚本中“窃取”其中一些参数以用于自己的用途。例如,正在解释的脚本看不到传给 Perl 解释器的“-w”参数,除非脚本看来需要它。shell 用空格字符隔开参数。

传给 Perl 的“-e”参数告诉 Perl 获取命令行中“-e”后的任何内容并将它当作脚本来运行。“-M”参数表示获取其后的任何内容并将该内容作为模块导入,类似于正规脚本中的“use ModuleName”。请参阅 perldoc perlrun 页面以获取有关 Perl 必须从命令行提供的开关的更多信息。

可能最好在这里举些示例。根据本专栏文章的精神,让我们使用一行程序。脚本的 -MData::Dumper -e’print Dumper -@ARGV’ 部分只是打印出了 @ARGV 数组的内容。

清单 1. 命令行参数
继续阅读“[转载]功能丰富的 Perl: 一行程序 101”

Perl健忘录

perl -lne 的作用
-l: line-ending handling Automatically adds or removes '\n' (处理行结束符,自动加上 \n 换行或者删除 \n 换行)

In effect(作用效果):
chomp()s everything on input 自动 chomp 输入分隔号
A godsend for one-liners

perl    [ -sTtuUWX ]
[ -hv ] [ -V[:configvar] ]
[ -cw ] [ -d[t][:debugger] ] [ -D[number/list] ]
[ -pna ] [ -Fpattern ] [ -l[octal] ] [ -0[octal/hexadecimal] ]
[ -Idir ] [ -m[-]module ] [ -M[-]'module...' ] [ -f ]
[ -C [number/list] ]
[ -P ]
[ -S ]
[ -x[dir] ]
[ -i[extension] ]
[ [-e|-E] 'command' ] [ -- ] [ programfile ] [ argument ]...

-n
代表遍历文件的内容,使 Perl 隐式地循环遍历指定的文件,并只打印规定的行。

-e
代表执行 perl 命令,一般 -e 后面接 ‘command’ 要执行的命令了,参数的顺序有时候也要注意的,我现在认为 -e 一般紧接着要执行的命令,所以 -e 作为最后一个参数放在那里。

-p
使 Perl 隐式地循环遍历指定的文件,同时打印所有的行。

-P
使要运行的脚本在 Perl 编译之前通过 C 预处理程序。

请注意:-p 开关和 -n 开关的使用。当您想显式打印数据时,使用 -n 开关。-p 开关隐式地将 print $_ 语句插入到 -n 开关所产生的循环中。因此,-p 开关更适用于对文件进行的完全处理,而 -n 开关更适用于选择性文件处理,这样的处理只需打印特定数据。

我现在喜欢使用 -l 参数,用来给每一个输出加 \n. 例如

$ perl -le 'print "Hello World!"'

常用的 Perl 单行实例

继续阅读“Perl健忘录”