代码之家  ›  专栏  ›  技术社区  ›  oneself

在Emacs中匹配regexp和分组

  •  1
  • oneself  · 技术社区  · 15 年前

    我尝试匹配一个字符串,然后使用分组创建一个新字符串:

      (let ((url (browse-url-url-at-point)))
        (if (string-match "http://domain/\\([0-9]+\\)/\\([a-z]+\\)\.\\([0-9]+\\)" url)
      (setq filename (concat (match-string 1 url) "_" (match-string 2) "." (match-string 3) ".xml"))))
    

    当我(打印URL)得到以下信息时

    "http://domain/1234/action.1234567"
    

    当我(打印文件名)成功匹配后,我得到以下信息:

    #("1234_ublish.eport s.xml" 0 5 nil 5 11 (face nxml-element-local-name-face fontified t) 11 12 nil 12 17 (face nxml-element-local-name-face fontified t) 17 18 (fontified t) 18 19 (face nxml-attribute-local-name-face fontified t) 19 23 nil)
    

    为什么会这样?

    3 回复  |  直到 15 年前
        1
  •  4
  •   mamboking    15 年前

    您没有为第二个和第三个匹配字符串包含可选的字符串参数。根据匹配字符串文档,“如果上次搜索是通过字符串上的“字符串匹配”进行的,则应给出字符串。”

        2
  •  3
  •   viam0Zah    15 年前

    我发现了问题。

    结果是(字符串匹配)需要将原始字符串作为参数,否则它将返回包含奇怪值的奇怪列表(不确定这些值是什么)。

    无论如何,将代码更改为:

     (let ((url (browse-url-url-at-point)))
        (if (string-match "http://domain/\\([0-9]+\\)/\\([a-z]+\\)\.\\([0-9]+\\)" url)
      (setq filename (concat (match-string 1 url) "_" (match-string 2 url) "." (match-string 3 url) ".xml"))))
    

    解决了问题

        3
  •  2
  •   Community CDub    7 年前

    AS mamboking already mentioned ,的文档字符串 match-string 告诉你所有关于:

    (match-string NUM &optional STRING)
     ⋮
    STRING should be given if the last search was by `string-match' on STRING.
    

    如果你也检查 string-match 的文档,您将看到它建议使用 match-beginning match-end 去拿火柴。这些是C中的内置函数。

    (if (string-match "\\([a-z]\\)" "123 test string")
      (match-beginning 1)) ;; 4
    

    这些函数只返回匹配文本的开始或结束位置,这就是为什么 匹配字符串 也需要原始字符串。使用时 search-forward re-search-forward , 比赛开始 比赛结束 将返回缓冲区位置,因此 匹配字符串 可以很容易地从缓冲区的内容中替换有趣的匹配项。

    你也可以看看 match-string-no-properties 其行为与 匹配字符串 Expect返回不带文本属性的匹配文本字符串。