정규식은 String.matches ()에서 작동하지 않습니다.


147

이 작은 코드 조각이 있습니다

String[] words = {"{apf","hum_","dkoe","12f"};
for(String s:words)
{
    if(s.matches("[a-z]"))
    {
        System.out.println(s);
    }
}

인쇄 예정

dkoe

그러나 아무것도 인쇄하지 않습니다 !!


41
Java matches는 시작 부분에 ^를, 정규 표현식 끝에 $를 넣습니다. 그래서 matches("[a-z]")실제로 대신에 / 대한 / ^ [az]와 $ 보일 것이다.
Robino

예 @Robino 당신은 절대적으로 맞습니다.
Mihir

1
확실히의 matches발생을 찾으려면 [a-z]모두 일치해야합니까? matches정규식에 대해 각각의 모든 문자를 개별적으로 확인 하지는 않습니다 .
PhilHibbs

@Robino : 해당 기능은 어디에 기술 / 문서화되어 있습니까?
Toru

@Toru String.Matches에 대한 Java 문서 페이지에서-다른 곳? "java string matches documentation"의 일반적인 Google은 최상위 결과에서 "str.matches (regex)는 표현식과 정확히 동일한 결과를 산출합니다." 중요한 단어는 "정확하게"입니다.
Robino

답변:


323

Java의 이름이 잘못된 .matches()메소드에 오신 것을 환영합니다 . 모든 입력을 시도하고 일치시킵니다. 불행하게도, 다른 언어들은 다음과 같이 따라 갔다 :

정규식이 입력 텍스트와 일치하는지 확인하려면 Pattern, a Matcher.find()매처 의 메소드를 사용하십시오.

Pattern p = Pattern.compile("[a-z]");
Matcher m = p.matcher(inputstring);
if (m.find())
    // match

입력 내용에 소문자 만 포함되어 있는지 확인하려면을 사용할 수 .matches()있지만 하나 이상의 문자를 일치시켜야합니다 . +에서와 같이 문자 클래스에 a 를 추가 하십시오 [a-z]+. 또는 사용 ^[a-z]+$하고 .find().


2
온라인에서 불완전한 튜토리얼 100 개를 발견했습니다. 좋은 것을 찾지 못했습니다. 의견 있으십니까?
John

설명에 대한 감사 @fge .matches(). 이 예제.find() 에서 왜 그렇게 느리게 작동 하는지 알고 있습니까?
Konstantin Konopko

3
다른 언어들과 어울리면 무슨 뜻 입니까? 내가 아는 바로는, 단지 C ++는 방법과 동등한이있다 - regex_searchregex_match. 파이썬에서는 re.match문자열의 시작 부분에서만 일치를 고정 \Apattern하고 파이썬 3.x는 좋은 .fullmatch()방법을 얻습니다 . JS, Go, PHP 및 .NET에는 일치를 암시 적으로 고정시키는 정규식 메소드가 없습니다. ElasticSearch, XML 스키마 및 HTML5 / Validators Angluar 패턴은 기본적으로 항상 고정되어 있습니다. Swift / Objective C에는 옵션으로 시작시 패턴을 고정하는 방법이 있습니다.
Wiktor Stribiżew

이것을 할 수있는 oneliner 방법이 있습니까?
추기경-모니카

44

[a-z]a와 z 사이 의 단일 문자 와 일치합니다 . "d"예를 들어 문자열이 그냥 이면 일치하고 인쇄되었을 것입니다.

[a-z]+하나 이상의 문자와 일치하도록 정규식을 변경해야합니다 .


12
물론 그것은 단일 문자와 일치하므로 정규 표현식이 수행합니다! 그러나 명확하지 않은 것은 (그리고 경우도 마찬가지입니다!) java 는 제공된 정규 표현식 주위에 접두사 ^와 접미사를 넣고 $원하지 않게 변경하고 이상한 버그를 만듭니다. 초기 정규 표현식의 의미가 아니기 때문에 그렇게하지 않아야합니다.
klaar

28

String.matches하위 문자열뿐만 아니라 전체 문자열이 정규식과 일치 하는지 여부를 반환합니다 .


3
정말 슬픈 현실은 당신이 옳다는 것입니다. 나는 그들이 왜 이런 식으로했는지 모르겠어요.
Hola Soy Edu Feliz Navidad

16

java의 정규 표현식 구현은 전체 문자열과 일치하려고합니다.

그것은 일치하는 부분을 찾으려고하는 펄 정규 표현식과 다릅니다.

소문자가 아닌 문자열을 찾으려면 패턴을 사용하십시오. [a-z]+

하나 이상의 소문자를 포함하는 문자열을 찾으려면 패턴을 사용하십시오. .*[a-z].*


자세한 내용은 여기
ycomp

3
왜 이것이 문서화되어 있지 않습니까?!
레오 오리엔 티스

12

익숙한

String[] words = {"{apf","hum_","dkoe","12f"};
    for(String s:words)
    {
        if(s.matches("[a-z]+"))
        {
            System.out.println(s);
        }
    }

4

나는 같은 문제에 한 번 직면했다.

Pattern ptr = Pattern.compile("^[a-zA-Z][\\']?[a-zA-Z\\s]+$");

위의 실패!

Pattern ptr = Pattern.compile("(^[a-zA-Z][\\']?[a-zA-Z\\s]+$)");

위의 (및 내의 패턴으로 작업했습니다 ).


2

정규식 은 길이가 1 인 문자열과 만 일치하므로 [a-z]일치하지 않습니다 .dkoe[a-z]+


-1

()일치하는 패턴을 캡처하려면 최소한 다음 과 같이 패턴을 수정해야합니다.

String[] words = {"{apf","hum_","dkoe","12f"};
for(String s:words)
{
    if(s.matches("(^[a-z]+$)"))
    {
        System.out.println(s);
    }
}

대괄호는 아무것도 변경하지 않았습니다.
Touniouk

괄호가 matches없는 @Touniouk 에는 출력이 없습니다.
MohsenB

-3

다음을 수행하여 패턴 대소 문자를 구분하지 않을 수 있습니다.

Pattern p = Pattern.compile("[a-z]+", Pattern.CASE_INSENSITIVE);
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.