본문 바로가기

About/Computer

regex 정규식 예제

출처 : http://www.freeimage.kr/bbs/board.php?bo_table=tip_preg&wr_id=14

 

 

---------------------------------------------------

 

 

정규식: 숫자로 시작되는 행 매치


^\d.*

^ : 행의 맨 처음을 의미
\d : 0~9까지의 아라비아 숫자 1자를 의미
.* : 모든 문자를 의미. 즉 임의의 갯수의 글자들

따라서 위의 정규식은, 숫자로 시작하는 모든 행에 매치됩니다. 아래과 같습니다:

Vim을 정규식 편집기로 사용 - Regular __EXPRESSION__ Editor




정규식: 숫자로 끝나는 행 매치


.*\d$

$ : 행의 끝을 의미


=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=



문서 중에서, 숫자로만 이루어진 행만 찾는 정규식입니다. 0에서 9까지의 아라비아 숫자 외의 다른 글자가 섞여 있으면 찾지 않습니다.

울트라에디트/EmEditor 정규식


에디터의 "찾기" 대화상자에서, Use Regular __EXPRESSION__s 에 체크해 주어야 "정규식으로 찾기"가 작동합니다. (정규식이 아닌 일반 텍스트를 찾기 위해서는 이 옵션을 해제해야 합니다.)

숫자로만 이루어진 행 찾기는 다음과 같습니다.

^\d+$


^ : 행의 첫부분
\d : 0~9까지의 숫자
+ : 바로 앞의 글자 (여기서는 숫자)가 1개나 1개 이상 있음. (즉 숫자가 최소한 1개 있음)
$ : 행의 마지막 부분




Vim / Gvim 정규식


Vim(VI) 에디터에서는 다음과 같이 합니다.

/^\d\+$


/ : 이것은 정규식의 일부가 아니고 빔 에디터의 찾기 명령입니다.

또한, 이렇게 + 앞에 \ 를 붙여야 합니다.


=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

알아두면 너무 편리한 에디트 플러스에서 사용하는 정규식..

잃어버리기 전에 하나씩 메모..


^ 는 라인의 제일 처음을 말한다.

$ 는 정규식에서 라인의 제일 마지막을 말한다. (주위 : 원래 ^, $ 는 정규식에서 데이터의 시작과 끝을 의미)

| 는 and를 의미한다. 이 기호의 양쪽에 있는 두 글자를 모두 찾습니다. (ex. java|jsp|servlet)

\t 탭 문자를 찾습니다.

\n 줄 바꿈 문자를 찾습니다

. 모든 문자를 찾습니다.

[] 대괄호 범위의 모든 문자를 찾습니다. (ex. "[ab]" 는 "a"와 "b"를 모두 찾습니다. "[a-z]" a부터 z까지입니다.)
- 한글검색: 한글의 범위는 "ㄱ-ㅎ, 가-힣" 입니다.

[^] 대괄호 범위의 모든 문자를 제외한 문자를 찾습니다. (ex. "[^a-z]" a~z까지의 문자를 제외합니다.)
- 주의: 괄호안에서 ^와 괄호밖에서 ^의 용도를 잘 생각하라..
* 0번 또는 그 이상의 문자를 찾습니다. (ex. "j[a*]" 는 java, jad ... 의 ja를 검색합니다.)

() 식을 해석하는 순서를 바꾸거나 식을 태그로 표시할 때 사용합니다.



참고.. (http://blog.naver.com/satmania?Redirect=Log&logNo=90008546174)

"ab*" a뒤에 0 이상의 b가 있는 문자열 ("a", "ab", "abbb", 등)
"ab+" 위와 동일 하지만 최소한 하나 이상의 b가 있어야 함 ("ab", "abbb", 등)
"ab?" b가 하나 있을 수도 있고 없을 수도 있음 (ab 또는 a)
"ab{2}" a뒤에 2개의 b가 있는 문자열 ("abb"); "ab{2,}" a뒤에 최소한 2개 이상의 b가 있는 문자열 ("abb", "abbbb", 등.);"ab{3,5}" a뒤에 3개에서 5개 사이의 b가 있는 문자열 ("abbb", "abbbb", 또는 "abbbbb").
{ }를 사용할 대는 반드시 첫 번째 숫자는 적어야 됨을 유의합니다. ((O) "{0,2}", (X) "{,2}"). 또한 '*', '+', '?'는 각각 "{0,}", "{1,}", "{0,1}"와 같습니다.

이제 ()를 사용해서 하나의 문자가 아닌 여러 문자를 지정하는 방법을 알아봅니다.

"a(bc)*": a 뒤에 "bc"가 0또는 그이상의 수만큼 있는 문자열
"a(bc){1,5}": a 뒤에 "bc."가 1에서 5번 들어 있는 문자열

또 다른 특수문자로는 OR 연산을 하는 '|'를 들 수 있습니다.

"hi|hello": "hi"나 "hello"가 들어 있는 문자열
"(b|cd)ef": "bef" 또는 "cdef"
"(a|b)*c": a와 b가 섞여서 여러번 나타나고 그뒤에 c가 붙어있는 패턴

'.' (period)는 어떤 한 문자를 의미합니다.

"a.[0-9]": a뒤에 한 문자와 숫자가 붙어 있는 패턴

"^.{3}$": 3문자로만 되어 있는 문자열

[]표현은 문자열의 해당 위치에 사용될 수 있는 문자를 표현하는데 사용합니다.

"[ab]": a또는 b ("a|b"와 동일한 표현);

"[a-d]": 소문자 'a'에서 'd'까지 ("a|b|c|d"또는 "[abcd]"와 동일);

"^[a-zA-Z]": 영문자로 시작하는 문자열

"[0-9]%": % 문자 앞에 하나의 문자가 붙어 있는 패턴

",[a-zA-Z0-9]$": 영문자, 숫자로 끝나는 문자열 패턴

[]에서 '^'를 표현의 가장 처음에 사용하면 나타나서는 안 되는 문자를 지정할 수 있습니다. (예> "%[^a-zA-Z]%" 두 % 사이에 영문자가 없는 패턴)

"^.[$()|*+?{"같은 특수 문자는 백슬레쉬('')를 사용해서 escape될 수 있습니다( 역자 주 : escape 이란 다른 말로 literal로 탈출한다라고 할 수 있습니다 즉 특수문자로 인식되지 않고 일반 문자로 인식되게 합니다). 사용하는 관점에서 보면 백슬레쉬도 PHP3의 문자열에서 escape되어야 하기 때문에 예를 들어 "($|?[0-9]+"같은 정규표현식은 ereg("($|?[0-9]+", $str) 와 같이 사용됩니다 (이 표현식은 무얼 검사하는 걸까요? ^^;(이건 역자가 한 말이 아닙니다))

하지만 []안에서는 특수문자가 모두 효력을 읽게 되기 때문에 이 법칙을 벗어남을 기억하세요 []안에서는 백슬레쉬를 포함한 모든 특수문자들이 그 힘을 읽습니다 (예> "[*+?{}.]"는 말그대로 '*', '', '+', '?', '{', '}', '.' 문자를 의미합니다. 그리고 regex man 페이지에 나오듯이 ']'문자 자체를 포함하려면 문자들 리스트의 첫 번째에 위치시킵니다('^'가 있으면 '^'뒤에). '-'를 포함하려면 첫 번째 또는 마지막 문자로 지정하고 '-'문자가 영역의 경계 (예> a에서 -까지)일 경우 영역지정 문자의 두 번째 경계로 지정([a--])합니다.

완벽한 설명을 하려면 대조 순서(collating sequences), 문자 클래스(character classes), 동일 클래스(equivalence classes)에 대해서도 다루어야 하지만 이 글에서는 별 상관관계가 없기 때문에 regex man 페이지를 참고하도록 합니다.



활용

(ja+)[a-zA-Z]* : ja로 시작하는 모든 문장을 찾습니다.

less..

-Validating Money Strings (금액 문자열 검사하기)

ok 이제 우리는 여기서 배운 것을 뭔가 실질적인 것에 적용 시켜봅시다. 사용자가 입력한 금액을 검사하는 정규표현식에 대해 알아봅니다. 금액은 "10000.00" 와 "10,000.00", 와, 센트 없이, "10000" 와 "10,000" 이렇게 4가지 방법으로 사용됩니다. (역자주 : 달러와 센트 군요 蝁,.蝁)

다음 정규표현식을 기초로 시작해 봅시다.

^[1-9][0-9]*$

이 정규표현식은 0으로 시작하지 않는 어떠한 수인지를 검사합니다. 하지만 "0"도 통과되지 못합니다. 그래서 다음과 같이 수정합니다.

^(0|[1-9][0-9]*)$

말로 표현하면 "0 이거나 0으로 시작하지 않는 수"입니다. 이제 수 앞에 -부호도 사용할 수 있게 수정해 봅니다.

<IFRAME style="POSITION: absolute; TOP: 0px; LEFT: 0px" id=google_ads_frame5 height=15 marginHeight=0 src="http://googleads.g.doubleclick.net/pagead/ads?client=ca-pub-7068950390217293&output=html&h=15&slotname=6573595829&w=728&lmt=1278308802&flash=10.1.53.64&url=http%3A%2F%2Furin79.com%2Fzb%2Futdae%2F805286&dt=1278308806987&shv=r20100625&prev_slotnames=9517529369%2C4200335054%2C3556923471%2C6573595829&correlator=1278308805690&frm=0&adk=3058334509&ga_vid=816310672.1277724238&ga_sid=1278308806&ga_hid=1422541435&ga_fc=1&u_tz=540&u_his=0&u_java=1&u_h=1050&u_w=1680&u_ah=1016&u_aw=1680&u_cd=32&u_nplug=0&u_nmime=0&biw=1251&bih=674&ref=http%3A%2F%2Fwww.google.co.kr%2Fsearch%3Fhl%3Dko%26newwindow%3D1%26complete%3D1%26q%3D%25EC%25A0%2595%25EA%25B7%259C%25EC%258B%259D%2B%25EB%25A1%259C%2B%25EC%258B%259C%25EC%259E%2591%25ED%2595%2598%25EB%258A%2594%2B%25EB%25AC%25B8%25EC%259E%2590%25EC%2597%25B4%26aq%3Df%26aqi%3D%26aql%3D%26oq%3D%26gs_rfai%3D&fu=0&ifi=5&dtd=141&xpc=ZeGbnY0qFN&p=http%3A//urin79.com" frameBorder=0 width=728 allowTransparency name=google_ads_frame marginWidth=0 scrolling=no></IFRAME>

^(0|-?[1-9][0-9]*)$

이 뜻은 "0 이거나 -이 있을 수 있는 수이고 이 수는 0으로 시작하지 않는다"입니다. 이제 좀 느슨하게 하고 유저가 0으로 시작하는 수도 입력할 수 있도록 해봅니다. 금액에 필요없는 -부호도 없애버립니다. 그리고 선택사항인 소수점 부분 패턴도 넣어서 다음 정규표현식이 나옵니다.

^[0-9]+(.[0-9]+)?$

하이라이트된 부분은 소수점(.)이 항상 최소한 하나이상의 수와 붙어 있어야 함을 의미합니다. 그러므로 예를 들면 "10."은 통과되지 못하고 "10" 과 "10.2"는 통과합니다.

^[0-9]+(.[0-9]{2})?$

이제 소수점 뒤에 반드시 2개의 수가 붙어 있어야 합니다. 이게 너무 심하다 싶으면 다음과 같이 해서

^[0-9]+(.[0-9]{1,2})?$

소수점 뒤에 하나의 숫자만 올 수도 있게 합니다. 이제 1000단위를 구분하는 ','를 표현해 봅니다.

^[0-9]{1,3}(,[0-9]{3})*(.[0-9]{1,2})?$

"1~3개의 숫자와 그 뒤에 ','와 3개의 숫자로 이루어진 부분이 0개 또는 그 이상이 붙어 있는 패턴". 쉽죠? 이제 ','도 선택사항(옵션:option)으로 만들어 봅니다.

^([0-9]+|[0-9]{1,3}(,[0-9]{3})*)(.[0-9]{1,2})?$

이게 전부입니다. 여기서 '+'를 '*'로 바꾸면 빈 문자열도 통과되는 패턴이 됩니다. 함수호출할 때 백슬래쉬 문자 escape하는 것 (역자 : /를 //로) 잊지 마세요. 일단 문자열이 검사되어 지면 str_replace("," , "" , $money) 함수로 ','를 없애버리고 double로 형 변환을 해서 산술연산에도 사용할 수 있게 합니다.

- Validating E-mail Addresses (E-mail 주소 검사하기)

이제 e-mail 주소를 살펴봅시다. e-mail주소는 3부분으로 구성됩니다. : user 명(@왼쪽편에 있는 모든 것), '@', 그리고 서버명(나머지 부분들) user명은 대문자 또는 소문자와 숫자, '.' '-', '_'로 구성됩니다. '_'를 제외하면 서버명도 마찬가지입니다. user 명은 .으로 시작하거나 끝나지 않습니다. domain명도 마찬가지입니다. 또한 .이 연속으로 있을 수도 없고 . 사이에는 최소한 하나 이상의 문자가 있어야 합니다. 이제 user명 부분을 검사하는 정규표현식을 만들어 봅시다.

^[_a-zA-Z0-9-]+$

이 정규표현식은 아직 .을 지원하지 않습니다. 다음과 같이 수정합니다.

^[_a-zA-Z0-9-]+(.[_a-zA-Z0-9-]+)*$

말로 하면 "최소한 하나의 유효한 문자(valid character)와 그 뒤에 .과 유효문자들로 구성된 부분이 0또는 그 이상이 있는 패턴"입니다.

좀 간단하게 하기 위해 이 정규표현식을 ereg()대신에 eregi()함수에 사용합니다. eregi()함수는 대소문자를 구분하지 않기 때문에 "a-z"와 "A-Z"같이 두 개의 영역을 지정하지 않아도 되는 이점이 있습니다.(둘 중 어떤 것이라도 상관없음)

^[_a-z0-9-]+(.[_a-z0-9-]+)*$

서버명의 경우 '_'만 제외하고는 동일합니다.

^[a-z0-9-]+(.[a-z0-9-]+)*$

이제 '@'를 중심으로 서로 붙여서 다음과 같이 만들어 냅니다.

^[_a-z0-9-]+(.[_a-z0-9-]+)*@[a-z0-9-]+(.[a-z0-9-]+)*$


=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

예제로 정규식을 이해해 봅시다.

#set $a = "hello"#
#set $b = ["hello", "world"]#
#print $a#
#stop#


조건 :
1. 모든 문장은 #로 시작해서 #로 끝난다
2. #로 시작하여 공백이 나오거나 #로 끝나기 전까지는 영어 소문자만 가능하다
3. 이후 나오는 문자는 영어 소문자, $, =(1~2개), [, ", ,(콤마), (공백) 만 사용가능하다
4. 큰따옴표 ""사이의 문자는 아무런 제약을 받지 않는다. 모든 문자 및 특수문자 사용가능
5. ["hello", "world"]같은식으로 두개이상의 아무런 제약을 받지 않는 큰따옴표 문자가 존재한다 (4번 규약 무한 반복 가능)
6. 두개이상의 공백이 있을수 있다


나의 경우에는 먼저 여러종류의 사용가능한 코드를 생각해 내고 거기에 맞추어 조건을 생각해 냈다.

이제 내가 원하는 문자만 검색할수 있도록 해보자.

1. 모든 문장은 #로 시작해서 #로 끝난다는 조건이 있다. 일단 그 사이에는 어떤 문자가 있어도 상관없다.
시작과 끝을 #로 한다고 하니 #로 설정한다. 그 중간에는 우선 어떤 문자가 와도 상관없으니 아무문자와 매치 되는 .을 쓰고 0개~무한 반복을 뜻하는 *을 쓰자. 혹시 한개이상의 문자가 필요하다면 +를 사용하면 된다.
결과 : #.*#

2. #로 시작하여 공백이 나오거나 #로 끝날때까지는 영어 소문자만 가능하다고 한다. 영어 소문자 리스트에 Arrange설정을 하자. 공백이 있어도 되고 없어도 되는 경우이므로 0~무한 매치인 *를 사용한다. 있는 경우에는 2개 이상이 될수도 있음을 분명히 하자. 공백문자(스페이스, 탭등)을 뜻하는 [\s]를 사용하자. [[:space:]]와 같은 문법도 클래스 형태로 제공하므로 사용해도 된다.
결과 : #[a-z]+[\s]*#

3. 이후 나오는 문자는 변수명과 = [ , " (공백) 등만 사용 가능하다. =는 1개나 2개만 사용가능하다는것도 잘 이해해 두자. '?'의 경우 반복없이 한번만 있을수도 있고 없을수도 있다는 뜻이다.
큰따옴표 안에는 아무런 제약을 받지 않는다고 한다. .*을 이용해 주면 모든 문자에 매치될수 있을것이다.
결과 : #[a-z]+[\s]*[a-z$]+[\s]*={1,2}[\[]?[\s]*\".*\"[\s]*[\]]?[\s]*#

4. "hello", "world"같이 여러개가 설정 가능하다고 한다. 어떻게 해야 할까? 그룹()으로 설정하면 된다.
한개는 무조건 있어야 하는것이고 두번째부터는 없을수도 있고 여러개일수도 있다. (blahblah)*식으로 그 그룹에 정의된 단위대로 0개이상의 반복을 할수 있다.
결과 : #[a-z]+[\s]*[a-z$]+[\s]*={1,2}[\[]?[\s]*\".*\"([\s]*,\".*\")*[\s]*[\]]?[\s]*#

최종 결과 :

#[a-z]+[\s]*[a-z$]+[\s]*={1,2}[\[]?[\s]*\".*\"([\s]*,\".*\")*[\s]*[\]]?[\s]*#

어떤가요?

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

정규식(정규표현식)에서, 문자열의 시작과 끝을 지정하는 방법입니다. 만약 foo 라는 문자열을 매치시키되, foo만으로 이루어진 문자열을 찾아야 한다면 다음과 같이 합니다:

^foo$


위와 같이 하지 않으면, fooooooo 또는 zzzzfoo 또는 zzzzfooaaaaa 이런 문자열 속의 foo까지 모두 매치되어 버립니다.

^ (캐럿 기호)는 문자열의 시작을 의미하고, $ (달러 기호) 는, 문자열의 마지막을 의미합니다. 그러나 개행문자까지는 포함 안됩니다. 말 그대로 문자열의 끝일 뿐입니다.


foo로 시작하는 모든 단어들을 찾으려면 다음과 같이 하고
^foo


foo로 끝나는 모든 단어들을 찾으려면 다음과 같이 합니다.
foo$

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

정규식에서 "모든 문자"를 다 선택하는 기호는 ".*" (따옴표 제외) 입니다. 즉, 마침표와 별표입니다. 도스의 와일드카드와 달리 그냥 별표(*;애스터리스크 기호)로는 되지 않습니다. 반드시 점을 붙여야 합니다.

예를 들어, apple 이런 문자열이 있을 때,

a.*e

이렇게 하면 apple 이라는 단어 전체가 매치됩니다. a로 시작되고 e로 끝나는 단어는, a와 e 사이에 무엇이 있든지 상관없이 매치됩니다.

.*

이렇게 하면 모든 텍스트가 다 선택됩니다.


아무 문자 딱 한 개만 매치하는 기호는?


"." (따옴표 제외) 입니다. 즉, 마침표입니다.

app.e

이렇게 하면 apple 이라는 단어가 매치됩니다. 그러나 소문자L이 2개 들어 있는 applle 이런 단어는 매치되지 않지 않습니다. 딱 1개의 아무 문자만 매치되는 것입니다.


=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
정규식에서 물음표(?), 마침표(.), 별표(*), 백슬래쉬(\) 문자는, 정규식 자체를 형성하는 특수문자이기에, 이 문자들 자체를 있는 그대로 매치시키려면, 앞에 백슬래시 기호를 덧붙여서 이스케이프해 주면 됩니다. 다음 예제와 같습니다.

Hello? 라는 단어가 있을 때, 물음표까지 매치시키려면, 물음표 앞에 백슬래쉬(\) 기호를 붙여서 이렇게 합니다.
Hello\?

이렇게 하면 물음표까지 매치됩니다.


Hello. 라는 단어가 있을 때, 마침표까지 매치시키려면, 점 앞에 백슬래쉬(\) 기호를 붙여서 이렇게 합니다.
Hello\.

이렇게 하면 마침표까지 매치됩니다. 위와 같이 하지 않고 그냥 "Hello." 이런 정규식을 사용하면 "HelloZ" 이런 문자열까지 매치되어 버립니다.


Hello* 라는 단어가 있을 때, 별표 즉 애스터리스크 기호까지 매치시키려면, 별표 앞에 백슬래쉬(\) 기호를 붙여서 이렇게 합니다.
Hello\*

이렇게 하면 별표까지 매치됩니다.


Hello\ 라는 단어가 있을 때, 백슬래쉬(\) 기호까지 매치시키려면, 백슬래시 기호를 2중으로 붙여서 이렇게 합니다.
Hello\

이렇게 하면 백슬래시 1글자가 매치됩니다.

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

'About > Computer' 카테고리의 다른 글

rpmbuild 사용법  (1) 2012.11.26
인터넷 프로토콜 서브넷 차트(IPv4)  (1) 2012.11.16
정규식  (2) 2012.04.12
itunes 에서 대체 이 문제는 왜 나는것인가?  (1) 2012.03.14
xfs_repair  (1) 2012.02.28