#정규표현식
2023-07-27 MetaWord meta regex일단 관련 내용을 옮겨서 모아 놓자.
휴고 타입으로 만드는게 맞나? 그러려면 reference 캡처를 하는게 맞다. 그리고 작성하고 기록할만 하면 남기고 아니면 버린다. 여기에 작성된 정보로 바로 BIB 로 뽑아 낼 수 있다. 굳이 org 파일로 관리를 안해도 될 수도 있다. 아무튼 핵심은 내가 정리한 자료만 내것이라는 것이다.
NOTE Emacs regular expressions in practice
:TITLE: Emacs regular expressions in practice :BTYPE: webpage :AUTHOR: :YEAR: 2023 :CUSTOM_ID: :ID: bc8f3b80-5869-4c3a-9761-e4d394d92eda
Emacs has a few ways to operate on regexp matches, such as:
isearch
query-replace
keep-lines
flush-lines
To make our life easier, we can practice with the built-in regexp-builder
or the third-party package visual-regexp
. This demo will rely on the latter.
If you have the manual you can run C-h r i regexp
to get to the relevant chapter. Do it!
백슬래시 부분은 꼭 읽어야 한다. emacs#Regexp Backslash
Line boundaries
The caret ^
denotes the beginning of the line.
The dollar sign $
marks the end.
Match all lines that start with a space:
Emacs Emacs Emacs Emacs Emacs
And all that end with a capital S
:
emacs emacS emacS emacs emacs emacs emacS emacS
헤드라인을 네로우 하면 여기에 집중할 수 있다. 여기서 말하는 것은 isearch-regex 를 이용해서 라인 바운더리를 오가는 것이다. 만약 맨 뒤에 S 만 있는 라인을 가려면 isearch-toggle-regexp
에서 S$ 을 입력하면 된다. evil 에도 뭔가 있을 텐데 프롯은 정통파라
Remove or keep lines
Remove the empty lines. Then keep the ones that contain “username”.
<username><![CDATA[name]]></username> emacs emacS emacS emacs emacs emacs emacS emacS
<userName><![CDATA[nom]]></userName> emacs emacS emacS emacs emacs emacs emacS emacS
<username><![CDATA[name]]></username> emacs emacS emacS emacs emacs emacs emacS emacS
whitespace-mode
를 켜니까 공백이 다 보인다. 와. 몰랐다. SPC t w
에 바인딩 되어 있네.
마우스로 영역 잡고 flush-lines
^$ 하니까 빈 라인이 다 사라졌다. 와우! 그 다음에 keep-lines
username 을 적으면 username 이 없는 라인은 다 사라진다.
The dot character
The dot or full stop .
means matches every character except the newline.
Match these words using their common part ired
as a string.
dired fired mired tired wired
> Mark saved where search started [2 times] 이게 뭔가? set-mark 를 어떻게 꺼내 쓰는가?
Character sets and ranges
A set of individual characters is marked between brackets []
.
Sets can be written as ranges:
Range | Scope |
---|---|
[a-z] | all lower cases alphabetic characters |
[A-Za-z] | all upper or lower case letters |
[a-z0-9] | lower case alphabet or numbers 0 through 9 |
[abcd1234] | letters a,b,c,d and numbers 1,2,3,4 |
Match both of those using a character set for the first letter:
emacs Emacs
Match those that end with a number:
Emacs emacs-27 emacs-26 GNU emacs
해보자! 어떻게 하나면! 잘 된다.
Difference between postfix operators ?, +, *
“Postfix” means that it comes after a given set and alters its scope. “포스트픽스"는 주어진 집합 뒤에 와서 그 범위를 변경하는 것을 의미합니다.
?
match the previous term zero or one time. +
match the previous term one or more times. *
match the previous term zero or as many times as possible.
Match the s
optionally:
day days
Use prote
followed by a postfix:
prot prote proteeee
어떻게 하는가요? 프롯은 isearch 를 사용한다. 뭐든 좋다. 기본은 기본대로 해야 된다. 잠시만.
Grouped matches
A group is enclosed inside escaped parentheses \(GROUP\)
.
Match both of these, including the optional suffix ig
:
conf config
> 보자 보자!
conf\(ig\)?
를 이용해서 해보자. 즉 그룹을 만들어서 해당 영역을 묶는 것이다. 유용하다.
Greedy versus non-greedy
Postfix charaacter are greedy by default. “Greedy” matches the longest possible part. Whereas “non-greedy” corresponds to the shortest.
A non-greedy variant is used when the postfix is followed by ?
.
Using the .*
construct, match items both greedily and not:
Hello world Hello world world world world
> ** Multiple groups
Match the alphabetic and numeric parts in two separate groups.
emacs27 emacs26 emacs25 emacs24
Literal hyphen and dot
Match the hyphen as part of the alphabetic group and the dot as part of the numeric one.
emacs-27.1 emacs-26.3 emacs-25.2
Exclude sets
To exclude a set you prepend a caret sign: [^SET]
Match every line except those that start with a capital letter.
GNU Emacs org-mode regexp emacs_lisp Linux guix
Alternative groups with literal brackets
Use a character sets that matches name
and nom
.
name nom
Then:
- Match the
username
variants’[name]
or[nom]
. - Replace the match with
[PROT]
.
<username><![CDATA[name]]></username> <nameuser><![CDATA[nam]]></nameuser> <userName><![CDATA[nom]]></userName> <nameuser><![CDATA[nome]]></nameuser>
Either match
To target either set, use \|
.
Prepend vr/
to the first group
and match
on each line.
`(group-0 ((group (:inherit modus-theme-intense-blue)))) `(group-1 ((group (:inherit modus-theme-intense-magenta)))) `(group-2 ((group (:inherit modus-theme-intense-green)))) `(match-0 ((match (:inherit modus-theme-refine-yellow)))) `(match-1 ((match (:inherit modus-theme-refine-yellow))))
Running elisp functions on groups
Run elisp by escaping the comma \,
and then following it with a symbol inside parentheses: \,(FUNCTION)
.
Using the .ired
pattern from earlier, run a replace command where you must execute the upcase
function on the second/middle match. Keep the rest in tact.
direddireddired firedfiredfired miredmiredmired tiredtiredtired wiredwiredwired
Emacs Evil mode regular expression search and replace
Emacs Evil mode regular expression search and replace - Emacs - makble :website:
One of the things I miss about VIM in Emacs is :%s
command, which allows you input pattern and replace text in one step. The Emacs M-x query-replace-regexp
do the same thing but a bit annoying, you need to input regular expression first then press enter, input replace text and press enter again and you need to press !
to execute replace for remaining matches or q
to quit or other moves. So many steps and confirmations, even just pasting I need paste two times. If you already accustomed to VIM’s way of search and replace, you would not like the Emacs way.
This makes me stay away from it for a long time. Sometimes I will copy the content of Emacs buffer to VIM and do substitution there. The Evil mode solved this problem and better than both of VIM and Emacs. You can use all Emacs features, but also have the access to most part of VIM.
The Evil mode search and replace is different things mixed together. Like VIM, you can type everything in one step, just input :%s
and input the rest. But it also use the Emacs regular expression syntax. The best thing is it highlight matches while you typing and show all kinds of hints message in minibuffer if the syntax is wrong or no matches found(this is the same as isearch-forward-regexp
), if you want to highlight all matches, input :%s///g
first and then backward a few characters to start write regular expression, you can see what will be replaced before execute substitution.
There is an Emacs plugin anzu
can highlight matches on the fly but you can not input pattern and replace text in one step, actually the rest is the same as Emacs except the highlight part. In VIM you can enable set incsearch
, but it only works for /
search not for %s
. I don’t yet know whether there is a VIM plugin can highlight matches on the fly for substitution. Seems there is no built in support for this.
Emacs 에서 VIM 에 대해 그리워하는 것 중 하나는 패턴을 입력하고 텍스트를 한 번에 바꿀 수있는 :%s
명령입니다. 이맥스의 M-x query-replace-regexp
는 같은 기능을 하지만 정규식을 먼저 입력한 후 엔터를 누르고 바꾸기 텍스트를 입력한 후 다시 엔터를 눌러야 하고, 나머지 일치하는 부분에 대해 바꾸기를 실행하려면 =!=를, 종료하거나 다른 동작을 하려면 =q=를 눌러야 하는 등 조금 번거롭습니다. 붙여넣기만 해도 두 번이나 붙여넣기를 해야 할 정도로 많은 단계와 확인이 필요합니다. 이미 VIM 의 검색 및 바꾸기 방식에 익숙하다면 Emacs 방식이 마음에 들지 않을 것입니다.
그래서 오랫동안 멀리하고 있습니다. 때때로 Emacs 버퍼의 내용을 VIM 에 복사하고 거기에서 대체를 수행합니다. 이블 모드는 이 문제를 해결해 주었고, VIM 과 이맥 모두보다 낫습니다. 모든 Emacs 기능을 사용할 수 있을 뿐만 아니라 VIM 의 대부분에 액세스할 수 있습니다.
이블 모드의 검색과 바꾸기는 서로 다른 기능이 섞여 있습니다. VIM 과 마찬가지로 모든 것을 한 번에 입력할 수 있으며 =:%s=만 입력하고 나머지는 입력하면 됩니다. 하지만 이 모드 역시 Emacs 정규식 구문을 사용합니다. 가장 좋은 점은 입력하는 동안 일치하는 부분을 강조 표시하고 구문이 잘못되었거나 일치하는 항목이 없는 경우 미니 버퍼에 모든 종류의 힌트 메시지를 표시한다는 것입니다(=isearch-forward-regexp=와 동일). 모든 일치 항목을 강조 표시하려면 =:%s///g=를 먼저 입력한 다음 몇 문자를 뒤로 돌려 정규식 작성을 시작하면 대체를 실행하기 전에 대체될 내용을 확인할 수 있습니다.
일치하는 항목을 즉석에서 강조 표시 할 수 있지만 패턴을 입력하고 텍스트를 한 번에 바꿀 수는 없으며 실제로 강조 표시 부분을 제외한 나머지는 Emacs 와 동일합니다. VIM 에서 set incsearch
를 활성화 할 수 있지만 /
검색에만 작동하고 %s
에는 작동하지 않습니다. 대체를 위해 즉석에서 일치 항목을 강조 표시 할 수있는 VIM 플러그인이 있는지 아직 알지 못합니다. 이에 대한 기본 지원은 없는 것 같습니다.
- Emacs multi-occur Search All Occurrences and List Search Results
- Emacs Evil mode regular expression search and replace
- 3 Ways to Replace string in Emacs
My regex tips
:ID: 82b0bdfc-bddc-4c5a-a537-1e659b9d2af1
다름이 아니라, 내가 해결하고자 하는 예제를 넣는다. 알아야 할 수 있는 개념들이다.
[[data: 시작하는 링크 제거 방법
비슷한 예에서 다 응용하면 된다. 편하다. 일단 grep 으로 검색하고 embark 로 모은 뒤 wgrep 활성화후 수정해서 저장하면 된다.
\[\[.*\]\]
.* 이게 * 는 반복인데 .은 암거나 인가보다.
C-q 사용법
- C-q C-j : newline 편리하다. 괜찮다.
rg-menu 이용하면 증분 수정을 할 수 있다.
계속 범위를 줄여가면서 반영한다.
rg-menu -> file or directory -> 추출된 버퍼에서 rg-menu regex -> spacemacs/compleseus-wgrep-change-to-wgrep-mode -> iedit or replace -> ZZ
- % 넣고 추리면서 수정하면 편하다.
- / 로 regex 검색해서 혹시 안된 부분 커버
footnote 수정 방법
이게 난이도가 더 높다.