2009-05-02 11 views

Odpowiedz

21

Myślę, że chcesz coś takiego, napisany z flagą /x dodawania komentarzy i nieznaczących spacji:

 
/
    \b  # word boundary so you don't start in the middle of a word 

    (   # open grouping 
     [A-Z]  # initial uppercase 
     [a-z]*  # any number of lowercase letters 
    )   # end grouping 

    {2,} # quantifier: at least 2 instances, unbounded max 

    \b  # word boundary 
/x 

Jeśli chcesz go bez fantazyjny formatowania, po prostu usuń spacje i komentarze:

 
/\b([A-Z][a-z]*){2,}\b/ 

Jak wskazuje j_random_hacker, jest to trochę proste, ponieważ pasuje do słowa, które jest po prostu kolejnymi dużymi literami. Jego rozwiązanie, które mam rozszerzony o /x pokazać jakiś szczegół, zapewnia co najmniej jedną małą literę:

 
/
    \b   # start at word boundary 
    [A-Z]  # start with upper 
    [a-zA-Z]* # followed by any alpha 

    (?: # non-capturing grouping for alternation precedence 
     [a-z][a-zA-Z]*[A-Z] # next bit is lower, any zero or more, ending with upper 
      |      # or 
     [A-Z][a-zA-Z]*[a-z] # next bit is upper, any zero or more, ending with lower 
    ) 

    [a-zA-Z]* # anything that's left 
    \b   # end at word 
/x 

Jeśli chcesz go bez formatowania ozdobnym, po prostu usuń spacje i komentarze:

 
/\b[A-Z][a-zA-Z]*(?:[a-z][a-zA-Z]*[A-Z]|[A-Z][a-zA-Z]*[a-z])[a-zA-Z]*\b/ 

Wyjaśniam wszystkie te funkcje w Learning Perl.

+3

Czy jedno słowo pisane wielkimi literami (takie jak Perl lub Boing) nie jest również poprawnym słowem CamelCase?W takim przypadku kwantyfikator powinien wynosić {1,} lub po prostu + –

+0

@Barry: W wielu przypadkach spowodowałoby to więcej problemów niż ich rozwiązanie. Lubię wersje Briansa. @Brian: Co oznacza flaga/x, którego nie używasz w swoim ostatnim poleceniu? –

+0

Perl lub Boing nie są wielbłądowe, ponieważ nie są wyrazami złożonymi. –

7

Zakładając, że nie używasz regex zrobić ekstrakcję, i po prostu dopasowanie ...

[A-Z][a-zA-Z]* 

nie jest jedynym prawdziwym wymóg, to wszystkie litery i zaczyna się z dużej litery?

+2

Jest to odpowiednik regexu Briana z wyjątkiem mniej skomplikowanych. Możesz wykryć takie słowa, jak HellotheRe, co oczywiście nie jest poprawne CamelCase, ale żadne wyrażenie nie może powiedzieć, co tam jest. Po prostu umieść znaki graniczne i to powinno wystarczyć. – Unknown

+0

EDYCJA: Poprawiłem Twoje wyrażenie regularne, dodając ostatnią literę "z". –

+0

@j_random_hacker: whoops. Dzięki za złapanie tego. –

5

brian's i sharth's odpowiedzi będzie również zgłosić słowa, które składają się wyłącznie z wielkich liter (np FOO). To może, ale nie musi być to, co chcesz. Jeśli chcesz ograniczyć do zaledwie wielbłądziej obudowane słowami, które zawierają co najmniej jedną małą literę, zastosowanie:

/\b[A-Z][a-zA-Z]*[a-z][a-zA-Z]*\b/ 

Jeśli dodatkowo chcesz wykluczyć słowa, które składają się z jednej wielkiej litery, a następnie dowolną liczbę małych liter (np Perl), zastosowanie:

/\b[A-Z][a-zA-Z]*(?:[a-z][a-zA-Z]*[A-Z]|[A-Z][a-zA-Z]*[a-z])[a-zA-Z]*\b/ 

(Zasadniczo wymagamy ciąg, aby rozpocząć wielką literą i zawierać co najmniej jedną dodatkową literę i jedną małą literę; te dwa ostatnie mogą być wyświetlane w dowolnej kolejności.)

+0

Twój pierwszy przykład pasuje do rzeczy, które nie są wyrazami złożonymi, np. "Foo". Drugi jest nieco owłosiony do wczesnego rana w golfa. :) –

+0

@brian: Jak wiadomo, w przypadku wyrażeń regularnych często jest to kwestia "niektórych włosów potrzebnych". :) Mam nadzieję, że z drugiego akapitu tekstu wynika, że ​​pierwsze wyrażenie dopasuje "Foo" et al. (ponieważ celem drugiego wyrażenia jest właśnie wykluczenie tych dopasowań). –

0

Co na ten temat: /\b[A-Z]([a-z]+[A-Z]?)*\b/ ??

+0

Jaka jest kluczowa różnica twojego kodu od Briana? –

Powiązane problemy