주어진 다음 정규식 : 나는 소수성 테스트의 정규식 부분 밖에 설명 할 것이다 String s
반복으로 구성 String t
, 발견을 t
.
System.out.println(
"MamamiaMamamiaMamamia".replaceAll("^(.*)\\1+$", "$1")
); // prints "Mamamia"
작동 방법은 정규식 캡처입니다 (.*)
에 \1
, 다음이 있다면보고 \1+
를 다음과 같습니다. 은 Using ^
및 $
보장하지만이 경기는 전체 문자열이어야.
그래서 어떤 식으로 우리 String s
는의 "다수"인을 부여 받았으며 String t
정규 표현식은 그런 것을 찾을 것입니다 t
(가장 \1
욕심이 많기 때문에 가능한 가장 길다 ).
이 정규식이 왜 작동하는지 이해하고 나면 우선 OP 테스트의 첫 번째 대안을 무시하고 우선 순위 테스트에 사용되는 방법을 간단하게 설명합니다.
- 의 우선도를 테스트하려면
n
먼저 String
길이를 생성 n
하십시오 (같은 것으로 채워짐 char
)
- 정규식 캡처는
String
약간의 길이 (말의 k
에) \1
, 그리고 시도 일치하는 \1+
의 나머지String
- 일치하는 경우
n
의 적절한 배수 k
이며 따라서 n
소수가 아닙니다.
- 일치가 없습니다 경우, 그러한은
k
그 분할을 존재하지 않는 n
, 그리고 n
따라서 소수
.?|(..+?)\1+
소수 는 어떻게 일치합니까?
실제로는 그렇지 않습니다! 그것은 일치 String
길이가 NOT 소수!
.?
: String
길이 의 대체 일치 의 첫 번째 부분 0
또는 1
(정의에 의한 소수는 아님)
(..+?)\1+
: 대체의 두 번째 부분, 위에서 설명한 정규 표현식의 변형은 String
길이의 n
"배" String
길이 k >= 2
(즉 n
소수가 아닌 복합) 의 길이 와 일치 합니다.
- reluctant 수정자는
?
실제로 정확성을 위해 필요하지는 않지만 더 작은 것을 k
먼저 시도하여 프로세스 속도를 높이는 데 도움이 될 수 있습니다
명령문 의 !
boolean
보수 연산자에 유의하십시오 . 정규식이 일치 하지 않을 때가 가장 중요합니다! 이중 음의 논리이므로 혼란 스럽습니다.return
matches
n
단순화
다음은 코드를보다 읽기 쉽게 작성하기 위해 다시 작성하는 것입니다.
public static boolean isPrime(int n) {
String lengthN = new String(new char[n]);
boolean isNotPrimeN = lengthN.matches(".?|(..+?)\\1+");
return !isNotPrimeN;
}
위의 내용은 원래 Java 코드와 본질적으로 동일하지만 논리를 이해하기 쉽도록 로컬 변수에 할당 된 여러 명령문으로 나뉩니다.
다음과 같이 유한 반복을 사용하여 정규식을 단순화 할 수도 있습니다.
boolean isNotPrimeN = lengthN.matches(".{0,1}|(.{2,})\\1+");
또, 소정의 String
길이를 n
동일 가득 char
,
.{0,1}
n = 0,1
소수 가 아닌지 확인
(.{2,})\1+
소수가 아닌 n
적절한 배수 인지 확인합니다.k >= 2
꺼리는 수정자를 ?
설정 한 것을 제외 하고 \1
(명확성을 위해 생략) 위의 정규식은 원본과 동일합니다.
더 재미있는 정규식
다음 정규식은 비슷한 기술을 사용합니다. 교육적이어야합니다.
System.out.println(
"OhMyGod=MyMyMyOhGodOhGodOhGod"
.replaceAll("^(.+)(.+)(.+)=(\\1|\\2|\\3)+$", "$1! $2! $3!")
); // prints "Oh! My! God!"
또한보십시오
!new String(new char[n]).matches(".?|(..+?)\\1+")
과 같습니다!((new String(new char[n])).matches(".?|(..+?)\\1+"))
.