0

I have a file formatted as

abc|<hoge>
a|<foo> b|<foo> c|<foo>
family|<bar> guy|<bar>
a|<foo> comedy|<bar> show|<foo>
action|<hoge>

and want to search search strings by raw (Like "a comedy show" instead of a|<foo> comedy|<bar> show|<foo>) on emacs.

I believe using grep on lisp would be the easiest answer but I have not yet figured out how. Would someone enlighten me?

4

1 回答 1

1

Well, grep is a separate program (which you could also use). In Emacs, you'd use the function search-forward-regexp, which you can run using either M-x (hold Meta, usually Alt key, and press x) and then type search-forward-regexp and press Return.

You'll then need to key in the regexp to search. Put simply, it seems like you want to ignore |< something >, which in Emacs's variety of regexes is:

 |<[a-z]+> 

so you might search for e.g.

 a|<[a-z]+> comedy|<[a-z]+> show|<[a-z]+>

You can create a Lisp function to convert a string this way, by splitting it on spaces and adding the regex sequences:

(defun find-string-in-funny-file (s)                        ; Define a function
  "Find a string in the file with the |<foo> things in it." ; Document its purpose
  (interactive "sString to find: ")                         ; Accept input if invoked interactively with M-x
  (push-mark)                                               ; Save the current location, so `pop-global-mark' can return here
                                                            ; (usually C-u C-SPC)
  (goto-char 0)                                             ; Start at the top of the file
  (let ((re (apply #'concat                                 ; join into one string…
                   (cl-loop 
                    for word in (split-string s " ")        ; for each word in `s'
                    collect (regexp-quote word)             ; collect that word, plus
                    collect "|<[a-z]+> "))))                ; also the regex bits to skip
    (search-forward-regexp                                  ; search for the next occurrence
     (substring re 0 (- (length re) 2)))))                  ; after removing the final space from `re'

You can explore what those functions each do in the (online) Emacs Lisp manual; for example, pick from the menu "Help→Describe→Function" or press C-h f (Control+h, then f) and type interactive (RET) for the manual's documentation of that special form.

If you paste the above (defun) into the *scratch* buffer, and position the cursor after the final ) at the end, you can press C-j to evaluate it, and the function will remain with you until you close Emacs.

If you save it in a file named something .el, you can use M-x load-file to load it again in future.

If you then load your "funny" file, and type M-x find-string-in-funny-file, it'll search your file for your string, and leave the cursor on the string. If it's not found, you'll see a message to that effect.

BUGS: The function is less than spectacular style

于 2015-02-11T23:19:57.220 回答