正则表达式极简“入门”

正则表达式(Regular Expression)这个东西,之所以感觉难学,是因为几乎所有关于它的教程都很不友好,不是对初学者不友好,是对所有人不友好 —— 也许是因为绝大多数人即便是掌握了这个东西,也觉得实在它没办法对初学者友好罢。

瞬间提高自学能力的诀窍在于两个字:

别怕。

如果非要用四个字的话,就是:

啥都别怕。

不就是学个东西嘛,学不会也不会死人的,学得会是早晚的事情。


正则表达式,其实你之前已经用过,虽然当时你可能完全不明白自己再做什么。

通俗点讲,

正则表达式是用来匹配捕获特定字符串的工具;之后,我们还可以对匹配到、捕获到的对象进行处理,比如替换

OK,就这样了罢。这里请注意三个概念:

  • 匹配(Match)
  • 捕获(Capture)
  • 替换(Replace)

这两个概念掌握了,可以开始运用了,就算是入门了。入门之后就好办了,边用边学,边犯错边改进,最终达到精通的地步 —— 无论学什么不都是这样吗?

想象一下,我们有这么一串电话号码:

07700 900166
07700 900202
07700 900911
07700 900284
07700 900847
07700 900009
07700 900754
07700 900396
07700 900248
07700 900408
07700 900724
07700 900773

现在我们想把它们变成这样的格式显示:

(077)0090-0166
(077)0090-0202
(077)0090-0911
(077)0090-0284
(077)0090-0847
(077)0090-0009
(077)0090-0754
(077)0090-0396
(077)0090-0248
(077)0090-0408
(077)0090-0724
(077)0090-0773

那我们要怎么做才行呢?显然,手动一行一行地弄很麻烦啊!每行都要添加括号,删除空格,在加上减号作为四位分隔符……

在支持正则表达式的编辑器里(Atom 这方面真的很差,Sublimetext 真的强太多了),搜索(\d\d\d)(\d\d) (\d\d)(\d\d\d\d),替换为($1)$2$3-$4…… 好神奇,一下子就搞定了!

仔细看看每一个字符:\d 指的的任意数字,所以,07700 900773,其实就可以用 \d\d\d\d\d \d\d\d\d\d\d 搜索到(空格前面五位数字,空格后面六位数字)。

现在我们想要让它被替换为 (077)0090-0773 这样的格式…… 那么:

  • 我们要想办法“捕获”前三位,然后在其前后加上括号;
  • 捕获接下来的两位数字,以及空格之后的两位数字,要把他们拼起来(即,相当于把空格去掉);
  • 捕获最后四位数字,然后在此之前加上一个减号……

所以,我们在搜索的时候加上了括号() —— 括号就是用来捕获的……

(\d\d\d)(\d\d) (\d\d)(\d\d\d\d)

翻译成自然语言:

  1. \d\d\d\d\d \d\d\d\d\d\d 匹配这些电话号码,以便我们能在文档中搜索到所有能够匹配这个正则表达式的字符串;
  2. 为了后面能够处理(即,替换),我们分别捕获了四段字符串: (\d\d\d)(\d\d) (\d\d)(\d\d\d\d)
  3. 然后,我们用 $1 … $4 来表示我们捕获到的字符串,然后用我们想要的拼接方式去替换匹配到的字符串:($1)$2$3-$4……

差不多了,这就是“入门”,后面你要接着研究:

  • 各种为了精确匹配所需要的“符号”;
  • 匹配同一个类型的字符串可能有很多种方法;
  • 避免错误匹配其实并不容易……

而后你就反应过来了,上面用的正则表达式,实在是太愚蠢了!那你就想办法用更聪明的呗…… 谁也拦不住你。

还是那句话:反复使用,反复试错,没多久你就真的精通了。

至于深入一步的教程么,Google 喽……