3

私はelispで作業していて、アイテムのリストを表す文字列を持っています。文字列は次のようになります

"apple orange 'tasty things' 'my lunch' zucchini 'my dinner'"

そして私はそれを分割しようとしています

("apple" "orange" "tasty things" "my lunch" "zucchini" "my dinner")

これはおなじみの問題です。それを解決する上での私の障害は、正規表現ではなく、elispの詳細に関するものです。

私がやりたいのは、次のようなループを実行することです。

  • (while (< (length my-string) 0) do-work)

それはどこですかdo-work

  • に正規表現を適用\('[^']*?'\|[[:alnum:]]+)\([[:space:]]*\(.+\)するmy-string
  • \1結果リストに追加する
  • my-stringに再バインド\2

split-stringしかし、それを取得する方法や実行する方法がわかりませんreplace-regexp-in-string

この文字列を使用できる値に分割するにはどうすればよいですか?

(あるいは、「これがまだ見つけていない組み込みのemacs関数はどれですか?」)

4

4 に答える 4

5

似たようなものですが、正規表現はありません:

(defun parse-quotes (string)
  (let ((i 0) result current quotep escapedp word)
    (while (< i (length string))
      (setq current (aref string i))
      (cond
       ((and (char-equal current ?\ )
             (not quotep))
        (when word (push word result))
        (setq word nil escapedp nil))
       ((and (char-equal current ?\')
             (not escapedp) 
             (not quotep))
        (setq quotep t escapedp nil))
       ((and (char-equal current ?\')
             (not escapedp))
        (push word result)
        (setq quotep nil word nil escapedp nil))
       ((char-equal current ?\\)
        (when escapedp (push current word))
        (setq escapedp (not escapedp)))
       (t (setq escapedp nil)
        (push current word)))
      (incf i))
    (when quotep
      (error (format "Unbalanced quotes at %d"
                     (- (length string) (length word)))))
    (when word (push result word))
    (mapcar (lambda (x) (coerce (reverse x) 'string))
            (reverse result))))

(parse-quotes "apple orange 'tasty things' 'my lunch' zucchini 'my dinner'")
("apple" "orange" "tasty things" "my lunch" "zucchini" "my dinner")

(parse-quotes "apple orange 'tasty thing\\'s' 'my lunch' zucchini 'my dinner'")
("apple" "orange" "tasty thing's" "my lunch" "zucchini" "my dinner")

(parse-quotes "apple orange 'tasty things' 'my lunch zucchini 'my dinner'")
;; Debugger entered--Lisp error: (error "Unbalanced quotes at 52")

ボーナス:引用符を「\」でエスケープすることもでき、引用符のバランスが取れていない場合は報告されます(文字列の最後に到達しましたが、開いた引用符に一致するものが見つかりませんでした)。

于 2012-10-11T10:00:13.437 に答える
3

をご覧になることをお勧めしsplit-string-and-unquoteます。

于 2012-10-11T13:37:38.403 に答える
3

一時バッファを使用してアルゴリズムを実装する簡単な方法を次に示します。replace-regexp-in-stringまたはを使用してこれを行う方法があるかどうかはわかりませんsplit-string

(defun my-split (string)
  (with-temp-buffer
    (insert string " ")     ;; insert the string in a temporary buffer
    (goto-char (point-min)) ;; go back to the beginning of the buffer
    (let ((result nil))
      ;; search for the regexp (and just return nil if nothing is found)
      (while (re-search-forward "\\('[^']*?'\\|[[:alnum:]]+\\)\\([[:space:]]*\\(.+\\)\\)" nil t)
        ;; (match-string 1) is "\1"
        ;; append it after the current list
        (setq result (append result (list (match-string 1))))
        ;; go back to the beginning of the second part
        (goto-char (match-beginning 2)))
      result)))

例:

(my-split "apple orange 'tasty things' 'my lunch' zucchini 'my dinner'")
  ==> ("apple" "orange" "'tasty things'" "'my lunch'" "zucchini" "'my dinner'")
于 2012-10-11T08:28:59.507 に答える