【问题标题】:String matching in emacs lisp matching arbitary stringemacs lisp中的字符串匹配匹配任意字符串
【发布时间】:2013-06-18 17:25:25
【问题描述】:

在 emacs lisp 中我只知道函数 string-match[-p],但我不知道将文字字符串与字符串匹配的方法。

例如假设我有一个由某个函数生成的字符串,并且想知道另一个字符串是否包含它。在很多情况下string-match-p 可以正常工作,但是当生成的字符串包含正则表达式语法时,它会导致意外的行为,如果包含的正则表达式语法无效,甚至可能崩溃(例如不平衡的引号\(\)) .

  1. emacs lisp 中的 some 函数是否类似于 string-match-p 但不解释正则表达式语法?
  2. 由于正则表达式匹配是在 C 中实现的,我假设匹配正确的正则表达式比某些 substring/string= 循环更快;是否有某种方法可以将任意字符串转义为匹配该字符串且仅匹配该字符串的正则表达式?

【问题讨论】:

    标签: regex emacs escaping elisp string-matching


    【解决方案1】:

    你在找regexp-quote吗?

    文档说:

    (regexp-quote STRING)
    
    Return a regexp string which matches exactly STRING and nothing else.
    

    而且我不知道您在 #2 中的假设是否正确,string= 应该更快...

    【讨论】:

    • 谢谢,这在大多数情况下都有帮助。此外,对于 68 个字符的查询字符串和 ≈ 300 个字符的字符串,使用 regexp-quote 在包含字符串的实现中进行搜索在编译代码中快 40 倍,在未编译代码中快 60 倍。然而,对于“string-starts-with”、“string-ends-with”,对于类似的输入大小,一个幼稚的 (string= (substring ...) ...) 实现在编译代码中快 4 倍(在未编译代码中慢 4 倍)。
    【解决方案2】:

    要么按照@trey-jackson 的建议使用regexp-quote,要么根本不使用字符串。

    Emacs 没有针对 string 处理进行优化;它针对缓冲区进行了优化。因此,如果您操作文本,您可能会发现 create a temporary buffer 更快,在此处插入文本,然后使用 search-forward 在该缓冲区中查找您的固定字符串(非正则表达式)。

    【讨论】:

    • 在我的系统上,with-temp-buffer 的开销约为 2e-6 秒(执行 (with-current-buffer (+ 1 1)) 10,000 次为 0.2 秒)。虽然可以忽略不计,但对于短字符串(≈10-30 个字符),开销比字符串函数(我尝试过的内置函数和我自己编写的一些函数)执行的时间大 ≈100-1000 倍。不过,我随时都会相信您,对于长字符串,缓冲区会提供更好的性能,所以感谢您的回答!
    【解决方案3】:

    也许cl-mismatch,类似于Common Lisp mismatch 函数?下面的示例用法:

    (mismatch "abcd" "abcde")
    ;; 4
    (mismatch "abcd" "aabcd" :from-end t)
    ;; -1
    (mismatch "abcd" "aabcd" :start2 1)
    ;; nil
    

    啊,对不起,我第一次没听懂这个问题。如果您想知道该字符串是否是另一个字符串的子字符串(可能从搜索字符串中的任何索引开始),那么您可以再次使用 cl-search,它类似于 Common Lisp search 函数。

    (search "foo\\(bar" "---foo\\(bar")
    ;; 3
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-12-24
      • 1970-01-01
      • 1970-01-01
      • 2016-01-23
      • 1970-01-01
      • 1970-01-01
      • 2011-03-20
      相关资源
      最近更新 更多