[regex] 유효한 IPv6 주소와 일치하는 정규식

압축 된 형식의 주소를 포함하여 유효한 IPv6 주소와 일치하는 정규식을 작성하는 데 문제가 ::있습니다 (각 바이트 쌍에서 생략되거나 선행 0이 생략 됨).

누군가가 요구 사항을 충족하는 정규식을 제안 할 수 있습니까?

각 바이트 쌍을 확장하고 결과를 더 간단한 정규식과 일치시키는 것을 고려하고 있습니다.



답변

@Factor Mystic의 답변을 POSIX 정규식으로 작업 할 수 없었기 때문에 POSIX 정규식과 PERL 정규식으로 작동하는 것을 작성했습니다.

다음과 일치해야합니다.

IPv6 정규식 :

(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))

쉽게 읽을 수 있도록 다음은 주요 OR 지점에서 별도의 행으로 분할 된 위의 정규 표현식입니다.

# IPv6 RegEx
(
([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|          # 1:2:3:4:5:6:7:8
([0-9a-fA-F]{1,4}:){1,7}:|                         # 1::                              1:2:3:4:5:6:7::
([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|         # 1::8             1:2:3:4:5:6::8  1:2:3:4:5:6::8
([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|  # 1::7:8           1:2:3:4:5::7:8  1:2:3:4:5::8
([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|  # 1::6:7:8         1:2:3:4::6:7:8  1:2:3:4::8
([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|  # 1::5:6:7:8       1:2:3::5:6:7:8  1:2:3::8
([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|  # 1::4:5:6:7:8     1:2::4:5:6:7:8  1:2::8
[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|       # 1::3:4:5:6:7:8   1::3:4:5:6:7:8  1::8  
:((:[0-9a-fA-F]{1,4}){1,7}|:)|                     # ::2:3:4:5:6:7:8  ::2:3:4:5:6:7:8 ::8       ::     
fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|     # fe80::7:8%eth0   fe80::7:8%1     (link-local IPv6 addresses with zone index)
::(ffff(:0{1,4}){0,1}:){0,1}
((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}
(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|          # ::255.255.255.255   ::ffff:255.255.255.255  ::ffff:0:255.255.255.255  (IPv4-mapped IPv6 addresses and IPv4-translated addresses)
([0-9a-fA-F]{1,4}:){1,4}:
((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}
(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])           # 2001:db8:3:4::192.0.2.33  64:ff9b::192.0.2.33 (IPv4-Embedded IPv6 Address)
)

# IPv4 RegEx
((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])

위의 내용을 더 쉽게 이해할 수 있도록 다음 “의사”코드는 위의 내용을 복제합니다.

IPV4SEG  = (25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])
IPV4ADDR = (IPV4SEG\.){3,3}IPV4SEG
IPV6SEG  = [0-9a-fA-F]{1,4}
IPV6ADDR = (
           (IPV6SEG:){7,7}IPV6SEG|                # 1:2:3:4:5:6:7:8
           (IPV6SEG:){1,7}:|                      # 1::                                 1:2:3:4:5:6:7::
           (IPV6SEG:){1,6}:IPV6SEG|               # 1::8               1:2:3:4:5:6::8   1:2:3:4:5:6::8
           (IPV6SEG:){1,5}(:IPV6SEG){1,2}|        # 1::7:8             1:2:3:4:5::7:8   1:2:3:4:5::8
           (IPV6SEG:){1,4}(:IPV6SEG){1,3}|        # 1::6:7:8           1:2:3:4::6:7:8   1:2:3:4::8
           (IPV6SEG:){1,3}(:IPV6SEG){1,4}|        # 1::5:6:7:8         1:2:3::5:6:7:8   1:2:3::8
           (IPV6SEG:){1,2}(:IPV6SEG){1,5}|        # 1::4:5:6:7:8       1:2::4:5:6:7:8   1:2::8
           IPV6SEG:((:IPV6SEG){1,6})|             # 1::3:4:5:6:7:8     1::3:4:5:6:7:8   1::8
           :((:IPV6SEG){1,7}|:)|                  # ::2:3:4:5:6:7:8    ::2:3:4:5:6:7:8  ::8       ::       
           fe80:(:IPV6SEG){0,4}%[0-9a-zA-Z]{1,}|  # fe80::7:8%eth0     fe80::7:8%1  (link-local IPv6 addresses with zone index)
           ::(ffff(:0{1,4}){0,1}:){0,1}IPV4ADDR|  # ::255.255.255.255  ::ffff:255.255.255.255  ::ffff:0:255.255.255.255 (IPv4-mapped IPv6 addresses and IPv4-translated addresses)
           (IPV6SEG:){1,4}:IPV4ADDR               # 2001:db8:3:4::192.0.2.33  64:ff9b::192.0.2.33 (IPv4-Embedded IPv6 Address)
           )

정규식을 테스트하는 스크립트를 GitHub에 게시했습니다 : https://gist.github.com/syzdek/6086792


답변

다음은 IPv4, IPv6 (전체 및 압축) 및 IPv6v4 (전체 및 압축) 주소의 유효성을 검사합니다.

'/^(?>(?>([a-f0-9]{1,4})(?>:(?1)){7}|(?!(?:.*[a-f0-9](?>:|$)){8,})((?1)(?>:(?1)){0,6})?::(?2)?)|(?>(?>(?1)(?>:(?1)){5}:|(?!(?:.*[a-f0-9]:){6,})(?3)?::(?>((?1)(?>:(?1)){0,4}):)?)?(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(?>\.(?4)){3}))$/iD'


답변

Python을 사용하는 것 같습니다. 그렇다면 다음과 같이 사용할 수 있습니다.

import socket

def check_ipv6(n):
    try:
        socket.inet_pton(socket.AF_INET6, n)
        return True
    except socket.error:
        return False

print check_ipv6('::1') # True
print check_ipv6('foo') # False
print check_ipv6(5)     # TypeError exception
print check_ipv6(None)  # TypeError exception

첫 번째 매개 변수로 inet_pton전달하면 IPv4 주소를 구문 분석 할 수있는를 얻기 위해 IPv6을 Python으로 컴파일 할 필요가 없다고 생각합니다 socket.AF_INET. 참고 : Unix가 아닌 시스템에서는 작동하지 않을 수 있습니다.


답변

IPv6 regex “에서 :

(\A([0-9a-f]{1,4}:){1,1}(:[0-9a-f]{1,4}){1,6}\Z)|
(\A([0-9a-f]{1,4}:){1,2}(:[0-9a-f]{1,4}){1,5}\Z)|
(\A([0-9a-f]{1,4}:){1,3}(:[0-9a-f]{1,4}){1,4}\Z)|
(\A([0-9a-f]{1,4}:){1,4}(:[0-9a-f]{1,4}){1,3}\Z)|
(\A([0-9a-f]{1,4}:){1,5}(:[0-9a-f]{1,4}){1,2}\Z)|
(\A([0-9a-f]{1,4}:){1,6}(:[0-9a-f]{1,4}){1,1}\Z)|
(\A(([0-9a-f]{1,4}:){1,7}|:):\Z)|
(\A:(:[0-9a-f]{1,4}){1,7}\Z)|
(\A((([0-9a-f]{1,4}:){6})(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3})\Z)|
(\A(([0-9a-f]{1,4}:){5}[0-9a-f]{1,4}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3})\Z)|
(\A([0-9a-f]{1,4}:){5}:[0-9a-f]{1,4}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\Z)|
(\A([0-9a-f]{1,4}:){1,1}(:[0-9a-f]{1,4}){1,4}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\Z)|
(\A([0-9a-f]{1,4}:){1,2}(:[0-9a-f]{1,4}){1,3}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\Z)|
(\A([0-9a-f]{1,4}:){1,3}(:[0-9a-f]{1,4}){1,2}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\Z)|
(\A([0-9a-f]{1,4}:){1,4}(:[0-9a-f]{1,4}){1,1}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\Z)|
(\A(([0-9a-f]{1,4}:){1,5}|:):(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\Z)|
(\A:(:[0-9a-f]{1,4}){1,5}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\Z)


답변

나는 Frank Krueger 의 대답을 강력하게 두 번째로해야 할 것 입니다.

IPv6 주소와 일치하기 위해 정규식이 필요하다고 말했지만 실제로 필요한 것은 주어진 문자열이 유효한 IPv6 주소인지 확인할 수있는 것이라고 가정합니다. 여기에는 미묘하지만 중요한 차이점이 있습니다.

주어진 문자열이 유효한 IPv6 주소이고 정규식 일치가 유일한 솔루션인지 확인하는 방법은 여러 가지가 있습니다.

가능하면 기존 라이브러리를 사용하십시오. 라이브러리에는 버그가 적고이를 사용하면 유지 관리 할 코드가 줄어 듭니다.

Factor Mystic 이 제안한 정규식 은 길고 복잡합니다. 작동 할 가능성이 높지만 예기치 않게 실패 할 경우 대처 방법도 고려해야합니다. 여기서 제가하려는 요점은 필요한 정규식을 직접 구성 할 수 없으면 쉽게 디버그 할 수 없다는 것입니다.

적합한 라이브러리가없는 경우 정규식에 의존하지 않는 고유 한 IPv6 유효성 검사 루틴을 작성하는 것이 더 나을 수 있습니다. 당신이 그것을 쓰면 당신은 그것을 이해하고 당신이 그것을 이해한다면 다른 사람들도 그것을 이해하고 나중에 유지할 수 있도록 그것을 설명하는 주석을 추가 할 수 있습니다.

다른 사람에게 설명 할 수없는 기능을 가진 정규 표현식을 사용할 때는주의하여 행동하십시오.


답변

나는 Ipv6 전문가는 아니지만 이것으로 더 쉽게 꽤 좋은 결과를 얻을 수 있다고 생각합니다.

^([0-9A-Fa-f]{0,4}:){2,7}([0-9A-Fa-f]{1,4}$|((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|$)){4})$

“유효한 ipv6입니다”라고 대답하는 것은 나에게 괜찮아 보입니다. 부분적으로 분해하려면 … 잊어 버리세요. 내 데이터베이스에 “unpecified adress”를 사용할 필요가 없기 때문에 지정되지 않은 주소 (: :)를 생략했습니다.

시작 :
^([0-9A-Fa-f]{0,4}:){2,7}<-압축 가능한 부분과 일치, 우리는 이것을 다음과 같이 번역 할 수 있습니다 : 2에서 7 사이의 콜론 사이에 16 진수 숫자가있을 수 있습니다.

뒤에 :
[0-9A-Fa-f]{1,4}$< ((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|$)){4}-16 진수 (선행 0 생략) 또는
<-Ipv4 주소


답변

이것은 loopback (:: 1)과 ipv6 주소를 잡습니다. {}를 +로 변경하고 :을 첫 번째 대괄호 안에 넣습니다.

([a-f0-9:]+:+)+[a-f0-9]+

ifconfig -a 출력 http://regexr.com/으로 테스트되었습니다.

Unix 또는 Mac OSx 터미널 o 옵션은 :: 1을 포함하여 일치하는 출력 (ipv6) 만 반환합니다.

ifconfig -a | egrep -o '([a-f0-9:]+:+)+[a-f0-9]+'

모든 IP 주소 (IPv4 또는 IPv6) 가져 오기 및 유닉스 OSx 용어에 일치하는 인쇄

ifconfig -a | egrep -o '([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}) | (([a-f0-9:]+:+)+[a-f0-9]+)'