我很难过试图创建一个排除组的Emacs正则表达式。 [^]
不包括集合中的单个字符,但我想排除特定的字符序列:类似于[^(not|this)]
,以便包含“不”或“this”的字符串不匹配。如何编写排除而非匹配的正则表达式,例如not(this | string)?
原则上,我可以写([^n][^o][^t]|[^...])
,但是还有另一种更清洁的方法吗?
我很难过试图创建一个排除组的Emacs正则表达式。 [^]
不包括集合中的单个字符,但我想排除特定的字符序列:类似于[^(not|this)]
,以便包含“不”或“this”的字符串不匹配。如何编写排除而非匹配的正则表达式,例如not(this | string)?
原则上,我可以写([^n][^o][^t]|[^...])
,但是还有另一种更清洁的方法吗?
首先:[^n][^o][^t]
不是解决方案。这也会排除像nil
([^n]
不匹配),bob
([^o]
不匹配)或cat
([^t]
不匹配)之类的词。
但它有可能建立与基本语法,做匹配字符串既不包含正则表达式not
也不this
:
^([^nt]|n($|[^o]|o($|[^t]))|t($|[^h]|h($|[^i]|i($|[^s]))))*$
这个正则表达式的模式是允许不是第一的任何字符字或单词的前缀,但不是全部单词。
+1,如果我曾经试图切换到Emacs,这将是不够的理由。任何人都可以*没有超前视力? :P – 2010-02-07 20:29:00
到目前为止,非常享受Emacs,这是我的第一个“什么......” – biocyberman 2015-08-03 19:57:05
这并不容易。正则表达式被设计为匹配的东西,这是他们所能做的。
首先:[^]
没有指定“排除组”,它指定了否定字符类。字符类不支持任何形式或形状的分组。它们支持单个字符(并且为了方便起见,字符范围)。就正则表达式引擎而言,您的尝试[^(not|this)]
相当于[^)(|hinots]
的100%。
三种方式可以导致了这种情况:
(not|this)
和排除任何匹配与你所处的环境的帮助(否定的比赛结果)我想知道为什么这个答案如此低调地上传,这是最清晰的答案! – 2014-08-04 14:26:22
@Yagamy因为它或多或少说“不起作用”,而显然有一种方法可以使它工作(即使是不切实际的更不得已而为之)。 – Tomalak 2014-08-05 05:24:19
我在这里没有看到“不起作用”的说法,甚至相反:您展示了三种可以解决问题的方式,第三种方式就像接受的答案一样。 – 2014-08-05 11:26:24
尝试使用M-x冲洗线。
很难相信接受的答案(来自Gumbo)实际上被接受了!除非它被接受,因为它表明你不能做你想做的。除非你有一个产生这样的正则表达式的函数(如Gumbo节目),编写它们将是一个真正的痛苦。
什么是真正的用例 - 你真的想要做什么? (a)这不是什么正则表达式所做的; (b)看到他链接的另一篇文章,有一个很好的解释,包括如何解决你的问题。
答案是使用正则表达式匹配你所做的而不是想要的,然后从初始域中减去它。IOW,不要试图让正则表达式做排除(它不能);在之后使用正则表达式排除,以匹配要排除的内容。
这就是每个使用正则表达式的工具的工作方式(例如,grep
):它们提供了一个单独的选项(例如通过语法),在匹配需要减去的东西后执行减法。
这听起来像你正在试图做负面的前瞻。即一旦达到某个分隔符,您就试图停止匹配。
Emacs不直接支持lookahead,但它支持非贪婪版本的*,+和?运算符(*?,+?,??),在大多数情况下可用于相同的目的。
因此,举例来说,匹配这段JavaScript函数体:
bar = function (args) {
if (blah) {
foo();
}
};
您可以使用此emacs的正则表达式:
function ([^)]+) {[[:ascii:]]+?};
这里我们停止一旦我们发现这两个元素序列“};”。 [[:ascii:]]用于“。”的instad。因为它工作在多行。
这与负向预测有点不同,因为};但是如果你的目标是提取所有东西直到那一点,你只需要使用一个捕获组\(和\)。
见emacs的正则表达式手册:http://www.gnu.org/software/emacs/manual/html_node/emacs/Regexps.html
作为一个侧面说明,如果你在写任何emacs的正则表达式时,一定要调用的Mx重新建造,这将带来了一个小的IDE针对写你的正则表达式当前的缓冲区。
匹配的逻辑测试字符串的使用情况下,我这样做:
;; Code to match string ends with '-region' but excludes those that has 'mouse'.
M-x ielm RET
*** Welcome to IELM *** Type (describe-mode) for help.
ELISP> (setq str1 "mouse-drag-region" str2 "mou-drag-region" str3 "mou-region-drag")
"mou-region-drag"
ELISP> (and (string-match-p "-region$" str1) (not (string-match-p "mouse" str1)))
nil
ELISP> (and (string-match-p "-region$" str2) (not (string-match-p "mouse" str2)))
t
ELISP> (and (string-match-p "-region$" str3) (not (string-match-p "mouse" str3)))
nil
我用这种方法来避免我讨论Over Here功能的缺陷:
我认为这是GNU ERE。 – Gumbo 2010-02-07 19:19:38
@Gumbo。 你是对的,谢谢 – Anycorn 2010-02-07 19:22:17
点击“regex-negation”标签查看一些类似的问题。 – finnw 2010-02-09 12:59:34