Với sự trợ giúp nhiều từ @nhahtdh trong câu trả lời này https://stackoverflow.com/a/21943960/3112803 Tôi thấy chia tay nó là giải pháp tốt nhất. Dưới đây là ví dụ về cách thực hiện trong PL/SQL
, nhưng nó có thể được thực hiện theo cách này trong các ngôn ngữ khác. Tôi sẽ làm tương tự trong ColdFusion
. Đối với PL/SQL
mẫu cần có dưới 512 ký tự vì vậy việc chia nhỏ nó hoạt động tốt và nó rất đơn giản để hiểu. Nó đã vượt qua tất cả các trường hợp thử nghiệm của tôi trong câu hỏi ban đầu.
if (
/* IPv6 expanded */
REGEXP_LIKE(v, '\A[[:xdigit:]]{1,4}(:[[:xdigit:]]{1,4}){7}\z')
/* IPv6 shorthand */
OR (NOT REGEXP_LIKE(v, '\A(.*?[[:xdigit:]](:|\z)){8}')
AND REGEXP_LIKE(v, '\A([[:xdigit:]]{1,4}(:[[:xdigit:]]{1,4}){0,6})?::([[:xdigit:]]{1,4}(:[[:xdigit:]]{1,4}){0,6})?\z'))
/* IPv6 dotted-quad notation, expanded */
OR REGEXP_LIKE(v, '\A[[:xdigit:]]{1,4}(:[[:xdigit:]]{1,4}){5}:(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}\z')
/* IPv6 dotted-quad notation, shorthand */
OR (NOT REGEXP_LIKE(v, '\A(.*?[[:xdigit:]]:){6}')
AND REGEXP_LIKE(v, '\A([[:xdigit:]]{1,4}(:[[:xdigit:]]{1,4}){0,4})?::([[:xdigit:]]{1,4}:){0,5}(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}\z'))
) then