js正则表达式语法大全_一条正则表达式闹的乌龙

“实战Elisp”系列旨在讲述我使用Elisp定制Emacs的经验,抛砖引玉,还请广大Emacs同好不吝赐教——如果真的有广大Emacs用户的话,哈哈哈。

序言

我要编写一个Elisp函数,其核心逻辑涉及到替换字符串中一个符合某种模式的子串。举个例子,字符串为"[2020-02-15 Sat 14:19]《业务逻辑需要关心同步还是异步吗?》",需要替换的是其中的[2020-02-15 Sat 14:19]

这个由日期和时间组成的前缀在每一次我按下C-c c t的时候会自动产生,因为在org-capture-templates中就是这么设置的

(setq org-capture-templates
      '(("t" "Todo" entry (file+headline "~/Dropbox/gtd/inbox.org" "Tasks")
         "* TODO %U%?n  :PROPERTIES:n  :CREATED_AT: %Un  :ID: %(uuidgen-4)n  :END:")))

更具体一点,它们产生自其中的转义序列%U(详情可以参见org-mode的文档Template expansion)。

经过一番不是特别仔细的搜索后,我决定用string-matchreplace-match函数来完成上述替换子串的需求。

然后便闹了两个乌龙。

string-match不支持扩展的正则语法

为了匹配形如[2020-02-15 Sat 14:19]这样的字符串,我的直觉便驱使我写出了这样的正则表达式

"^[d+-d+-d+ w+ d+:d+]"

在Node.js或其它支持Shorthand Character Classes的语言中,上面的正则表达式是可用的。

但是Elisp偏偏不是这样的语言!(Elisp所支持的正则表达式语法可以参见这篇文档)因此,在Elisp中只好用下面这个正则表达式

"^[[0-9]+-[0-9]+-[0-9]+ [A-Za-z]+ [0-9]+:[0-9]+]"

虽然Elisp不支持Shorthand Character Classes,但它确实支持Character Classes,但这样写出来的正则表达式更长了

"^[[[:digit:]]+-[[:digit:]]+-[[:digit:]]+ [[:alpha:]]+ [[:digit:]]+:[[:digit:]]+]"

我猜你宁可写前一种对吧。

replace-match不返回新字符串

这货是用来修改一个buffer中的内容的……

一种Workaround

最后我根据需求的实际情况,综合使用string-matchsubstring,以及format实现了替换子串的功能

(defun lt-org--starts-with-timestamp-p (text)
  "返回T或NIL表示输入字符串是否以一个inactive timestamp开头。"
  ;; Emacs的正则表达式并不支持如d和w这样的类,所以要写成[0-9]和[A-Za-z]的形式
  (string-match "^[[0-9]+-[0-9]+-[0-9]+ [A-Za-z]+ [0-9]+:[0-9]+]" text))

(defun lt-org--delay-timestamp (text new-timestamp)
  "用NEW-TIMESTAMP替换TEXT中的inactive timestamp。

如果TEXT没有以inactive timestamp开头,则直接添加NEW-TIMESTAMP。"
  (format "%s%s" new-timestamp
          (if (lt-org--starts-with-timestamp-p text)
              (substring text 22)
              text)))

过了很久后,我终于发现了在Elisp中做字符串替换的正确做法……

正确答案

只要用replace-regexp-in-string函数就足够了

(replace-regexp-in-string "^[[0-9]+-[0-9]+-[0-9]+ [A-Za-z]+ [0-9]+:[0-9]+]" "abc" "[2020-02-15 Sat 14:19]《业务逻辑需要关心同步还是异步吗?》")

结果为"abc《业务逻辑需要关心同步还是异步吗?》",替换很成功。

后记

如何在浩如烟海的知识(搜索引擎、在线文档)中找到自己需要的东西,也是一门学问啊。

阅读原文

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Linux正则表达式是一种用来匹配文本内容的表达式,它可以方便地在Linux系统中进行文本处理和搜索。下面是一份Linux正则表达式大全,包括常用的正则表达式语法和示例: 1. 字符匹配 正则表达式语法:字符 示例: * 匹配单个字符: ``` a 匹配'a'字符 ``` * 匹配多个字符: ``` [abc] 匹配'a'、'b'或'c'字符 [^abc] 匹配除'a'、'b'、'c'以外的任意字符 [a-z] 匹配小写字母a到z中的任意一个字符 [A-Z] 匹配大写字母A到Z中的任意一个字符 [0-9] 匹配数字0到9中的任意一个字符 ``` 2. 重复匹配 正则表达式语法:字符+、字符*、字符? 示例: * 匹配多个字符: ``` a+ 匹配一个或多个'a'字符 a* 匹配零个或多个'a'字符 a? 匹配零个或一个'a'字符 ``` 3. 边界匹配 正则表达式语法:^、$ 示例: * 匹配行首和行尾: ``` ^a 匹配以'a'字符开头的行 a$ 匹配以'a'字符结尾的行 ``` 4. 逻辑匹配 正则表达式语法:字符1|字符2 示例: * 匹配两种字符中的任意一种: ``` a|b 匹配'a'或'b'字符 ``` 5. 分组匹配 正则表达式语法:(字符) 示例: * 匹配分组中的字符: ``` (a) 匹配'a'字符 ``` 6. 转义字符 正则表达式语法:\字符 示例: * 匹配特殊字符: ``` \. 匹配'.'字符 \* 匹配'*'字符 \+ 匹配'+'字符 \? 匹配'?'字符 \( 匹配'('字符 \) 匹配')'字符 ``` 以上是Linux正则表达式的常用语法和示例,可以根据实际需求进行学习和使用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值