【问题标题】:Elegant regular expression to match all punctuations but not "'" in emacs Lisp?优雅的正则表达式匹配emacs Lisp中的所有标点但不匹配“'”?
【发布时间】:2009-12-12 21:44:29
【问题描述】:

我想匹配所有标点符号,但不匹配“'”,如“I'm”。例如,在下面的句子中:

I'm a student, but I'm also working. 
 ^not match  ^match ^not           ^match

我可以使用“[[:punct:]]+”匹配所有标点符号,但我很难从匹配模式中排除“'”。

当然,我可以使用类似下面的一些东西来通过枚举来表达,但是它很繁琐,尤其是考虑到中文的所有标点符号。 "[,.?!]"

请提出更优雅的解决方案。

提前致谢,

【问题讨论】:

    标签: regex regex-negation


    【解决方案1】:

    如果您的正则表达式支持环视,您可以这样做:

    (?!')[[:punct:]]
    

    简单的英语:如果向前看时没有单引号,则匹配任何标点符号

    【讨论】:

    • Emacs Lisp 有它自己的,嗯,unique 正则表达式语法,我怀疑它是否支持环视。 :-)
    • 我扫描了问题以找到 Yu 正在使用的正则表达式实现(没有提及任何内容),但忘记查看帖子的标题...... :)
    • 是的,实际上我也很困惑:gnu.org 上的 Emacs 手册说“不支持字符类,因此例如您需要使用 '[0-9]' 而不是'[[:digit:]]'.",但 Yu 说 "[[:punct:]]+" 有效。
    【解决方案2】:

    感谢 Bart 的回答和您所有的 cmets。受 Bart's 的启发,我检查了 emacs 似乎仍然不支持前瞻。但本着精神,我编写了以下代码:

    (defun string-match-but-exclude (regexp string exclude & optional start)

    "返回字符串中正则表达式的第一个匹配开始的索引,或 nil, 但排除正则表达式。 如果 case-fold-search' is non-nil. If third arg start is non-nil, start search at that index in string. For index of first char beyond the match, do (match-end 0). match-end' 和 `match-beginning' 也给出子字符串的索引,匹配会忽略大小写 由模式中的括号结构匹配。

    您可以使用函数 `match-string' 来提取子字符串 与正则表达式中的括号结构相匹配。"

    (let ((data nil))

    (and (string-match regexp string start)
    
       ;; keep the match-data for recovery at the end. 
    
       (setq data (match-data))
    
       (not (string-match (concat "[" exclusion "]") (match-string 0 string)))
    
       (progn (set-match-data data) t) ; To recover the match data, and make sure it produces t as returned value
    
       (match-beginning 0)
    
       ))
    

    )

    所以对于 (?!')[[:punct:]] string "'") 的等价表达式

    应该是

    (字符串匹配但排除 "[[:punct:]]" 字符串 "'")

    这可以完成工作,但没有那么优雅。它应该是对 emacs 的一个小补充,以使其成为内置支持。

    emacs 现在确实支持字符类。

    再次感谢。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多