문제

 

https://school.programmers.co.kr/learn/courses/30/lessons/72410

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

1단계 new_id의 모든 대문자를 대응되는 소문자로 치환합니다.
2단계 new_id에서 알파벳 소문자, 숫자, 빼기(-), 밑줄(_), 마침표(.)를 제외한 모든 문자를 제거합니다.
3단계 new_id에서 마침표(.)가 2번 이상 연속된 부분을 하나의 마침표(.)로 치환합니다.
4단계 new_id에서 마침표(.)가 처음이나 끝에 위치한다면 제거합니다.
5단계 new_id가 빈 문자열이라면, new_id에 "a"를 대입합니다.
6단계 new_id의 길이가 16자 이상이면, new_id의 첫 15개의 문자를 제외한 나머지 문자들을 모두 제거합니다.
     만약 제거 후 마침표(.)가 new_id의 끝에 위치한다면 끝에 위치한 마침표(.) 문자를 제거합니다.
7단계 new_id의 길이가 2자 이하라면, new_id의 마지막 문자를 new_id의 길이가 3이 될 때까지 반복해서 끝에 붙입니다.

[입출력 예]

nonew_idresult

예1 "...!@BaT#*..y.abcdefghijklm" "bat.y.abcdefghi"
예2 "z-+.^." "z--"
예3 "=.=" "aaa"
예4 "123_.def" "123_.def"
예5 "abcdefghijklmn.p" "abcdefghijklmn"

코드

class Solution {
    public String solution(String new_id) {
    	new_id = new_id.toLowerCase(); //1단계
    	new_id = new_id.replaceAll("[^a-z0-9\\-_\\.]", "");//2단계
    	new_id = new_id.replaceAll("\\.{2,}", ".");//3단계
    	new_id = new_id.replaceAll("^\\.", "");//3단계
    	new_id = new_id.replaceAll("\\.$", "");//4단계
    	if(new_id.isEmpty()) new_id="a"; //5단계
    	if(new_id.length()>15) new_id = String.copyValueOf(new_id.toCharArray(), 0, 15);//6단계
    	new_id = new_id.replaceAll("\\.$", "");
    	for(;new_id.length()<3;) new_id= new_id.concat(new_id.charAt(new_id.length()-1)+"" );//7단계
        return new_id;
    }
}

결론

정규식 기초를 보는 문제 같다. 

내가 생각하는 이 문제에서 바라는 정규식 수준을 키워드로 나열하면,

(반복) 수량자,  콤마(.)의 활용, 문자 클래스 문법([ ] , 이 대괄호 속 문법은 약간 다름), 이스케이프(\), 앵커

이 정도 같다.

 

개인적으로는 이정도만 알고, 필요할 때 더 공부하는 것이 맞는 것 같다. 

 

 

 

자바에서 정규식은 이스케이프 문제를 이스케이프화하는 부분이 실수하기 좋은 부분 같다. 

정규식의 예약문자를 이스케이프 하기 위한 "\"는 자바에서도 예약 문자라 이스케이프 해줘야 한다.

"\" => "\\"

System.out.println("[^a-z0-9\\-_\\.]");
System.out.println("\\.{2,}");
System.out.println("^\\.");
System.out.println("\\.$");
System.out.println("\\.$");
---------------------------------------------
[^a-z0-9\-_\.]
\.{2,}
^\.
\.$
\.$

실질적으로 자바가 먼저 입력받은 문자열을 파싱한 후, 아래 출력 값을 정규식 인자로 사용할 것이다.

 

 

이 부분을 조금 편하게 하는 제 방식을 다음과 같다.

//오류 무시하고 작성
System.out.println("[^a-z0-9\-_\.]");
//빈공간에!!
System.out.println("");
// [^a-z0-9\-_\.] 를 복붙, 이클립스가 자동으로'\'=>'\\' 치환해줌
System.out.println("[^a-z0-9\\-_\\.]");

--------------------------------------------------
위 결과를 ctrl -H 로 일괄 치환하면, 위험할 수 있는 이유
//오류 무시하고 작성
System.out.println("[^a-z0-9\\-_\\.]");
//빈공간에!!
System.out.println("");
// [^a-z0-9\\-_\\.] 를 복붙
System.out.println("[^a-z0-9\\\\-_\\\\.]"); 다른 부분은 이렇게 될 수도 있다

 


 

'자료구조&알고리즘 > Level1' 카테고리의 다른 글

성격 유형 검사하기  (0) 2022.09.26
신고 결과 받기  (0) 2022.09.24
올바른 괄호  (1) 2022.09.23
크레인 인형뽑기 게임  (1) 2022.09.21
성격 유형 검사하기  (0) 2022.09.17

스패로우 같은 취약점 점검 툴을 점검 결과로 

제가 있는 사이트에 기존 sql mapper 파일에서 500개 정도되는 Mybatis Sql Injection 취약점이 나왔습니다.

원인은 ${} 사용 때문입니다. 

${}를 전부 #{}로 바꿔줬습니다.

SELECT '${BIND1}' FROM TEST
WHERE ${BIND2} BETWEEN '${BIND3}' AND '${BIND4}'

저같은 경우는 notepad++ 로 수정했습니다. 

이클립스나 STS도 당연히 정규식을 지원합니다.

 

\$\{[^{}]*\}  

 

일반적으로 ${}  안쓰는 것이 좋습니다.

성능면에서도 #{} 가 더 좋습니다. DB에 Library Cache를 찾아서 실행하기 때문입니다.

SELECT #{BIND1} 
FROM DUAL

실제 DB질의는 "SELECT ? FROM DUAL" 로 나가고 

파라미터로 #{BIND1} 값이 나갑니다. 

 

+ Recent posts