정규 표현식은 javascript나 java에서 사용할 수 있다.
java 환경에서 "," 로 구분된 값을 배열로 추출하기 예 "," 앞뒤로 공백이 있으면 구분자에 포함, 정규식에서 Pattenr과 split 사용법
import java.util.regex.Pattern;
String pattern = "\\s*,\\s*";
String val = "aaa,bbb, ccc , ddd,eee";
Pattern p = Pattern.compile(pattern);
String[] tels = p.split(val);
String tel_no = "";
int i = 1;
for(String tel:tels) {
if(i < tels.length) {
tel_no = tel_no + "\n";
}else {
tel_no = tel_no ; // 마지막
}
i++;
}
System.out.println(tel_no); // tel_no 출력값
aaa
bbb
ccc
ddd
eee
"\\s*,\\s*" 패턴 내용을 확인해보면, \s 는 빈공백을 의미하고 java환경에서는 특수문자 표시를위해 \를 하나더 붙여준다. 그래더 \\s 가 빈 공백을 의미한다.
*는 0개 이상 반복을 의미하므로 \\s*는 빈공백을 0개 이상 반복한다는 의미.
그래서 구분자로 "," ", " " ," " , " " , " 등이 될 수 있다.
입력값과 출력값은 다음과 같게 된다.
"aaa,bbb, ccc , ddd,eee"
===>
aaa
bbb
ccc
ddd
eee
참고: www.javatpoint.com/java-pattern-split-method
coding-factory.tistory.com/529
javascript 환경에서 json index 값을 배열로 추출하기 [ ] 안에 있는 값 추출, 정규식에서 split 사용법
var cData = $('textarea[name=contentData]').val(); // 기존 json data
var JSONObject = JSON.parse(cData); // JSONObject로 변환
var pattern = /\w+\[|\]\[|\]/g;
var myPath = "JSONObject['Task'][0]['Guide']";
var myVal = "Hello~";
console.log(myPath.split(pattern)); // n+2개
var indexList = myPath.split(pattern);
for(var i = 0; i < indexList.length; i++){
indexList[i] = indexList[i].replace(/'/gi,""); // ' 제거
}
console.log(indexList); // Task 0 Guide
if(indexList.length == 4){
JSONObject[indexList[1]][indexList[2]] = myVal;
}else if(indexList.length == 5){
JSONObject[indexList[1]][indexList[2]][indexList[3]] = myVal;
}else if(indexList.length == 6){
JSONObject[indexList[1]][indexList[2]][indexList[3]][indexList[4]] = myVal;
}else if(indexList.length == 7){
JSONObject[indexList[1]][indexList[2]][indexList[3]][indexList[4]][indexList[5]] = myVal;
}
// $('textarea[name=contentData]').val(JSON.stringify(JSONObject, null, "\t")); // 탭 크기 간격
$('textarea[name=contentData]').val(JSON.stringify(JSONObject, null, 2)); // 2크기 간격
위 내용은 json data에서 임의의 key값을 선택한 후, value값을 "Hello~"로 치환하는 내용의 javascript 소스 이다.
이때 JSONObject['Task'][0]['Guide'] 이런 형태의 key값을 문자열 형태로 찾은후 치환하기 위해서는 변수 형태로 변환해야한다. 이경우 ' 값이 있어서 그런지 eval() 함수는 동작되지 않는다.
따라서 [ ] 안에 있는 인자값을 추출해서 변수로 만드는 작업이 필요하다.
/\w+\[|\]\[|\]/g
이 패턴은 구분자를 표시하는것으로 구분자는
1. 1개이상의 문자와 [
2. ][
3. ]
위 3개를 구분자로 정하고 있고 [ 가 특수문자이기 때문에 \ 를 추가하였다. 그리고 or 표시의 | 가 사용되었다.
그리고 구분자가 문자열의 앞뒤에 있어서 2개의 빈 구분값이 추가된다.
var indexList = {"", "'Task'", "0", "'Guide'", ""}; 이렇게 5개가 추출된다. 그리고 ' 를 제거하면
입력값과 출력값은 다음과 같게 된다.
JSONObject['Task'][0]['Guide'] ===> {"", "Task", "0", "Guide", ""}
참고: developer.mozilla.org/ko/docs/Web/JavaScript/Guide/%EC%A0%95%EA%B7%9C%EC%8B%9D
아래 링크에서 정규표현식이 잘 정리되어 있다. 참고하자
정규 표현식이란?
정규 표현식은 특정한 문자열의 규칙을 표현하는데 사용하는 형식언어이다.
(즉, 특정 규칙을 가지고 있는 문자열들; e.g. 1글자의 알파벳 소문자 = a,b,c,d,...)
보통 '문자열의 규칙'을 표현하기 위해서는 일반적인 조건문을 이용하면 복잡하게 표현해야하지만,
정규표현식을 이용하면 간결한 형태로 표현할 수 있다.
하지만, 규칙에 대하여 잘 숙지하지 않으면(규칙을 이해하고 있더라도 찬찬히 뜯어보기 전에는..)
알아보기 힘든 형태를 띄고 있는 것 또한 사실이다.
정규 표현식은 크게 문자와 메타문자로 구성된다.
아래에서 먼저 메타문자에 대하여 설명 한 뒤 메타문자와 문자를 이용하여 어떻게 정규표현식을 사용하는지 알아보도록 하자.
메타문자
메타문자는 문자를 표현하는 것 이외에 특정한 규칙을 표현하기 위한 문자들이다.
대부분의 경우 같은 메타문자들을 사용하지만 특정 종류에 따라 메타문자가 다른 경우도 있으므로
제대로 사용이 안될 경우 해당 정규식의 표현 방법을 찾아보아야 한다.
^x : 입력(줄) 시작 + x
x$ : x + 입력(줄) 끝
\Ax : 문자열의 시작(내부 줄바꿈 제외) + x
x\z : x + 문자열의 끝(내부 줄바꿈 제외)
. : 개행 문자를 제외한 임의의 문자 1개
x{n} : x가 n번 반복
x{n,} : x가 n번 이상 반복
x{n,m} : x가 n번 이상 m번 이하 반복
x? : 문자 x 또는 문자 없음(x{0,1})
x+ : x가 1번 이상 반복(x{1,})
x* : x 가 0번 이상 반복(x{0,})
--> +, *, {n,m}과 같이 여러 값을 가질 수 있는 규칙의 경우 기본적으로 greedy(좀 더 큰 결과값을 찾음)하게 동작하지만 ?기호를 붙이면 lazy(작은 결과를 찾음)하도록 동작한다.
x|y : x 또는 y
(x) : ()안의 내용을 캡쳐하여 그룹화 (레퍼런스 캡쳐 관련하여 Ref.2를 참조바람)
(x)(y) : ()안의 내용을 캡처하며 앞에서부터 그룹 번호를 부여함.
(?:y) : 캡쳐하지 않는 그룹을 생성
\n : (n은 1에서 9까지의 정수 [1-9])정규식 안 n번 괄호(그룹)의 최근 일치 부분(역참조)과 같음.
x(?=y) : y가 뒤 따라오는 x에만 일치
x(?!y) : y가 뒤 따라오지 않는 x에만 일치
[...] : Bracket expression이며 가능한 문자셋을 표시한다.(자세한 내용에 대해서는 후술)
정규 표현식에서 이스케이프 문자 '\' 뒤에 사용되는 문자를 특별하게 해석할 것을 요구하며,
특수한 문자(또는 문자집합)나 메타문자에서 먼저 사용하고 있는 글자(e.g. [](){}^$ 등)를 표시하기 위하여 사용한다.
\A : 문자열의 시작(내부 줄바꿈 제외)
\z : 문자열의 끝(내부 줄바꿈 제외)
\w : '_'를 포함한 알파벳 또는 숫자 [A-Za-z0-9_]
\W : 비 단어문자 [^A-Za-z0-9_]
\b : 길이가 0인 단어의 경계를 의미 즉, 매칭되는 결과물에는 경계가 포함되지 않는다(^\w | \w$ | \W\w | \w\W) (Ref.3)
\B : 단어의 경계가 아닌 것.
\d : 숫자 문자 [0-9]
\D : 숫자 문자가 아닌 것 [^0-9]
\xhh : hh(hex문자 2개)
\uhhhh : hhhh(hex문자 4개)
\f : 폼 피드(U+000C)
\n : 줄 바꿈(U+000A)
\r : 캐리지 리턴(U+000D)
\t : 탭(U+0009)
\v : 수직 탭(U+000B)
\s : 스페이스, 탭, 폼 피드, 줄 바꿈 문자를 포함한 하나의 공백문자 [ \f\n\r\t\v\u00a0\u1680\u180e\u2000-\u200a\u2028\u2029\u202f\u205f\u3000]
\S : \s가 아닌 모든 문자
\0 : 널 문자(U+0000)
\c : 컨트롤 문자(e.g. \cM 은 control-M(U+000D)와 일치함)
[](Bracket expression)
[]을 통하여 문자셋을 표현할 때에 주의할 점은 대괄호 안에서는 메타문자를 사용할 수 없거나
일반 문자가 다른 형태로 사용되게 된다.
[a-z] : a부터 z까지의 문자
[^ab] : a와 b를 제외한 모든 문자(^는 '줄의 시작'으로 처리되지 않고 not으로 처리된다.)
[ac] : a | c
[a.c] : a | . | c ('.'이 임의의 문자로 처리되지 않고, 문자 '.'로 처리된다.)
[\b] : 백스페이스
[-] : '-' 문자의 경우 문자로 인식되기 위해서는 []안에 첫 번째 혹은 마지막으로 위치하여야 한다.
[]] : '[' 문자의 경우 문자로 인식되기 위해서는 []안에 첫 번째 혹은 ^문자 바로 다음에 위치하여야 한다.
캐릭터 클래스(POSIX Extended)
[...]를 이용하여 문자셋을 표현하는 것이 가능하지만, 직관적으로 이해하기 힘든 점이 있을 수 있다.
때문에 직관적으로 이해하기 쉬운 형태로 문자셋을 표현할 수 있도록 캐릭터 클래스를 제공하고 있으며 그 내용은 다음과 같다.
(표준이 아닌 부분이 있을 수 있음)
[:alnum:] : 알파벳 및 숫자 [A-Za-z0-9]
[:alpha:] : 알파벳 [A-Za-z]
[:blank:] : 공백과 탭[ \t]
[:cntrl:] : 컨트롤 문자 [\x00-\x1F\x7f]
플래그
플래그를 이용하여 정규식의 검색 방법을 설정할 수 있다.
g : 전체 검색
i : 대소문자 무시
m : 여러 줄 검색
y : 현재 위치부터 검색
예제
정규표현식을 이용하여 특정 규칙이 있는 여러 문자열들을 검색할 수 있다.
e.g. 핸드폰 번호 찾기
홍길동 : 010-1234-5678
에서 핸드폰 번호를 찾고 싶다면
\d{3}-\d{4}-\d{4} 과 같이 값을 찾을 수 있다.
만약 이 중에서 끝 4자리가 5천이 넘는 숫자를 찾고 싶다면
\d{3}-\d{4}-[5-9]\d{3} 와 같이 찾을 수 있다.
속칭 '황금번호'와 같은 패턴을 찾고 싶다고 한다면 그룹의 역참조를 이용하여 찾아야 한다.
( 괄호('()')를 이용하여 그룹을 캡쳐하고 캡처한 내용을 \1~\9를 이용하여 역참조 한 형태로 반복시킨다.)
010-AAAA-BBBB 와 같은 형태라면
/010-(\d)\1{3}-(\d)\2{3}/ 와 같이 찾을 수 있을 것이다.
e.g. 파일 이름 찾아보기
자주 컴퓨터에서 파일을 찾는 사람들의 경우 윈도우의 검색이 느리기 때문에 'Everything'이라는 프로그램을 종종 사용하는 경우가 있다.
이 프로그램에서는 정규표현식을 이용한 찾기를 지원하는데(사실 Ctrl+f로 호출할 수 있는 대부분의 찾기가 정규표현식을 제공한다.)
정규표현식을 사용하지 못하는 경우 파일을 찾는데 애를 먹는 경우가 있다.
예를 들어 c:\ 안에 있는 모든 hello.c 파일과 hello.h 파일을 찾고싶다면
c:\\.+\\hello\.[ch]$ 라고 찾을 수 있을 것이다.
찬찬히 뜯어보면
c:\\ : c:\를 뜻하며 \가 메타문자로 해석하길 요구하는 글자이기 때문에 \\로 사용한다.
.+ : 1개 이상의 문자를 뜻한다. 따로 요구하지 않는 경우 정규표현식 검색은 greed(더 큰 것을 찾는다)하게 동작하기 때문에 최대한 많은 길이를 찾는다.
hello\. : hello. 을 뜻함.
[ch]$ : c 또는 h를 의미하며 $가 붙었기 때문에 이 줄의 끝일 경우에만 매칭된다.
와 같이 해석 가능하다.
e.g. 특수한 문자열 찾기
정규표현식을 익히는 좋은 방법중의 하나는 아주 긴 문자열들을 다뤄보는 것이다.
Python challenge 의 문제에 이런 문제가 있었는데, (물론 기억에 의존하는 것이기 때문에 정확히 같은 문제는 아니다.)
" 3개 이상의 큰 알파벳 사이에 같힌 글자를 찾아라" 였다.
그리고 문자열을 보면 알파벳 뿐만 아니라 온갖 기호들이 섞여있다.
여기서 매칭되는 문자를 찾기 위해서는 조건문을 꽤나 복잡하게 만들어야 하는데
정규표현식을 이용하면 간단하게 찾아낼 수 있다.
[A-Z]{3,} : 3개 이상의 큰 알파벳
[a-z] : 작은 알파벳
[A-Z]{3,} : 3개 이상의 큰 알파벳
이렇게 찾고 ()괄호를 이용해서 작은 알파벳을 캡쳐하면
[A-Z]{3,}([a-z])[A-Z]{3,}
와 같이 정규표현식이 나오고 결과값은 그룹으로 지정되어 리스트형태로 도출된다.
이런 방식으로 다양하게 정규 표현식을 사용 가능하니
필요할 때 보고 편리하게 사용해 보도록 하자.
Reference :
[1] https://en.wikipedia.org/wiki/Regular_expression
[2] http://www.regular-expressions.info/refcapture.html
[3] http://www.regular-expressions.info/wordboundaries.html
[4] http://www.nextree.co.kr/p4327/
출처: https://naudhizb.tistory.com/857 [Brise]
'자바 일반' 카테고리의 다른 글
자바 정규식, 한글이 있는지 (0) | 2021.05.31 |
---|---|
java split 사용 (구분자로 구별하기) (0) | 2021.04.13 |
JSON 데이터 정렬하여 보기, JSON Tree 구조 보기 (0) | 2020.08.07 |
JSONObject 를 MAP으로 변환, JSONArray를 List로 변환 샘플 (0) | 2019.05.30 |
쿠키 저장 및 조회 from JAVA (1) | 2019.05.28 |