본문 바로가기

Development/Java

[JAVA] 문자열에서 IP 주소 추출

728x90

1. 개요

로그 파일을 처리하거나 네트워크 트래픽 데이터를 분석해야 할때, Java에서 주어진 문자열에서 IP 주소를 추출해야 하는 경우가 많습니다.

먼저 IPv4 주소 형식을 살펴본 다음 Java의 정규 표현식(regex) 기능을 활용해 보겠습니다.

2. IP 주소에 대하여 간략하게 알아보기

IPv4 주소는 점으로 구분된 4개의 옥텟으로 구성되며, 각 옥텟은 0~255 사이의 숫자입니다.

즉, 유효한 IPv4 주소는 다음과 같습니다.

0.0.0.0
192.168.0.8
234.223.43.42
255.255.255.0

 

다음으로, IP 주소 형태의 모든 문자 시퀸스를 식별하는 정규식 패턴을 만들어 보겠습니다. 그런 다음 이 패턴을 적용하여 문자열에서 모든 IP 주소를 추출할 수 있습니다.

3. IP 주소와 일치하는 정규식 만들기

먼저 정규 표현식을 살펴보고 이것이 IP 주소와 일치하는 이유를 알아보겠습니다.

(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)[.]){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)

 

이 정규식에서 우리는 비캡처링 그룹(?:)을 사용했습니다.

비캡처링 그룹은 백레퍼런스를 생성하지 않고 대상을 그룹화합니다.

 

나중에 옥텟 패턴을 살펴보고 정규식 구조를 더 쉽게 이해해 보겠습니다. 그러면 정규식은 다음과 같습니다.

(?:(?:OCTET_PATTERN)[.]){3}(?:OCTET_PATTERN)

 

이 부분은 첫 번째 3개({3}) 옥텟과 그 뒤에 리터럴 도트와 마지막의 네 번째 옥텟과 일치합니다. 정규 표현식에서 "."가 단일 문자를 의미하지만 문자 클래스 "[.]"에 넣으면 리터럴 점 문자와 일치한다는 점을 언급하는 것이 좋습니다.

 

다음으로 OCTET_PATTERN을 자세히 살펴보겠습니다.

(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)

 

이 부분은 세 가지 가능성을 결합하여 0과 255 사이의 모든 유효한 숫자와 일치합니다.

이 내부 그룹 내의 각 옵션을 살펴보겠습니다.

  • 25[0-5] - 250에서 255까지의 숫자와 일치합니다.
  • 2[0-4][0-9] – 200~249까지의 숫자와 일치합니다.
  • [01]?[0-9][0-9]? – 0~199까지의 숫자와 일치합니다.

이제 정규 표현식을 이해했으므로 문자열에서 IP 주소를 추출하는 Java 메서드를 만들어 보겠습니다.

4. IP 주소를 추출하는 메서드 만들기

먼저, 앞서 이야기한 정규식에서 Pattern 인스턴스를 얻어보자.

static final Pattern IP_PATTERN = Pattern.compile("(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)[.]){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)");

 

문자열에는 여러 IP 주소가 포함될 수 있으므로 입력을 받고 추출된 IP 주소로 문자열 값 목록을 반환하는 매서드를 만들어 보겠습니다.

List<String> extractIP(String input) {
    Matcher matcher = IP_PATTERN.matcher(input);
    List<String> result = new ArrayList<>();
    while (matcher.find()) {
        result.add(matcher.group());
    }
    return result;
}

 

간단한 방법으로 matcher.find()를 사용하여 문자열을 반복하면서 각 일치하는 항목을 미리 초기화된 ArrayList에 수집합니다.

find()가 호출될 때마다 matcher.group()은 일치하는 하위 문자열(IP 주소)을 반환하고, 이를 result에 추가 합니다.

 

다음으로, 예상대로 작동하는지 확인 하기 위해 몇가지 테스트 데이터를 만들어 보겠습니다.

첫째, 문자열에 IP 주소가 포함되어 있지 않으면 빈 목록이 나올 것으로 예상합니다.

static final String INPUT1 = "No IP address here";
static final List<String> EXPECTED1 = Collections.emptyList();

 

문자열에 단일 IP 주소가 포함된 경우 다음과 같은 예상 IP 주소가 포함되어야 합니다.

static final String INPUT2 = "My local ip is 127.0.0.1";
static final List<String> EXPECTED2 = List.of("127.0.0.1");
 
static final String INPUT3 = "Another ip address is 192.168.42.42";
static final List<String> EXPECTED3 = List.of("192.168.42.42");

 

언급한 대로 각 옥텟은 0~255 사이어야 하므로 유효한 부분만 추출해야 합니다.

static final String INPUT4 = "Extract the valid part: 260.1.2.345";
static final List<String> EXPECTED4 = List.of("60.1.2.34");

 

입력한 유효한 IP 주소가 없으면 결과는 비어 있어야 합니다.

static final String INPUT5 = "No valid ip address 260.42.342.345";
static final List<String> EXPECTED5 = Collections.emptyList();

 

마지막으로, 이러한 입력을 사용하여 방법을 테스트 해보겠습니다.

assertEquals(EXPECTED1, extractIP(INPUT1));
assertEquals(EXPECTED2, extractIP(INPUT2));
assertEquals(EXPECTED3, extractIP(INPUT3));
assertEquals(EXPECTED4, extractIP(INPUT4));
assertEquals(EXPECTED5, extractIP(INPUT5));
assertEquals(EXPECTED6, extractIP(INPUT6));

 

테스트를 실행하면 모두 통과합니다. 따라서 이 방법은 문제를 해결합니다.

 

5. 결론

여기에서 Java에서 문자열 IP 주소를 추출하는 방법을 알아보았습니다. 정규 표현식을 사용하여 유효한 IPv4 주소를 감지하는 패턴을 만들었습니다. 그런 다음 정규식 패턴을 기반으로 주어진 문자열의 각 IP를 추출하는 방법을 알아보았습니다.

 

 


 

 

잘못된 부분이나 궁금한 사항은 댓글로 공유해주세요.

감사합니다.

 

 

 

 

 

참고 : https://www.baeldung.com/java-regex-extract-ip-address

 

728x90
반응형