How to fix this regex so it finds any word that contains at least one lower case letter grep -E -e '^[S][a-z]+, [^S][a-z]+' People.txt. The regex I am using know is to search for the second name that stars with capital S followed by comma and then space and then the first name that starts with any letter other than S. I want to fix this regex so it can also find a name like thisSbBBB, PaUU. I am using grep in the terminal of MacBook

Smith(second name) Paul(first name)

Text file

Smith, Paul
Pau, Smi
Smi, Smi

The output of the regex

Smith, Paul
  • Are you saying that your regular expression is matching the line SbBBB, PaUU?
    – Kusalananda
    Aug 16, 2021 at 11:42
  • Also, what do you call an alphabetic character? [a-z] matches a lot of characters (such as , ) which I wouldn't consider "alphabetic". And there are a lot of characters that I would call alphabetic (such the Greek letters which gave their name to the alphabet word or the uppercase Latin letters) which it doesn't match. Aug 16, 2021 at 11:43
  • It is my bad, I fixed the question. What I need is to fix the regex so it doesn't accept special characters and numbers. Aug 16, 2021 at 11:47
  • As far as I can see, that regex doesn't accept special characters or numbers, other than as the first letter after the comma, but you don't have any in that position in the input. Of course there could be such characters later in the line, after the part the RE matches, but that's slightly different. So what is it exactly that you're trying to do, and what you're trying to have the RE match?
    – ilkkachu
    Aug 16, 2021 at 11:54
  • I think I need to edit the question again because I got confused while writing the question question what I need exactly was to find any name that starts with s and the second name doesn't start with and must contain at least one lower case letter and it can contain upper case letter but at least one lower case letter. Aug 16, 2021 at 12:00

2 Answers 2

$ grep -Px 'S\pL*\p{Ll}\pL*, (?!S)\p{Lu}\pL*\p{Ll}\pL*' < your-file
Smith, Paul

Would report lines that start with S followed by any number of letters (characters with Letter property), followed by 1 lower case letter, followed by any number of letters followed by ", ", and an uppercase letter other than S and again a number of letters, at least one of which lower case.

PCRE \pL, like POSIX [[:alpha:]] is not limited to letters in alphabetic scripts; that includes word characters of any script. You could replace with [\p{Ll}\p{Lu}] to only match on letters that can be considered either lower or upper case or with \p{Latin} for any letter in the Latin script (as used in English, French, Spanish...) and (?=\p{Latin})\p{Ll} for a lower case letter in the Latin script only (not those in Greek, Cyrillic, etc scripts) for instance.

To use those [a-z] and only match on the 26 lowercase letters of the US ASCII charset, you'd need to fix the locale to C/POSIX and then you don't even need PCRE:

L='[A-Za-z]' Ll='[a-z]'
LC_ALL=C grep -x "S$L*$Ll$L*, [A-RT-Z]$L*$Ll$L*"

Note that it won't match on Serra, Éric for instance as that É is not matched by [A-RT-Z] in the C locale.


This might be what you're trying to do, using any POSIX compliant grep and assuming you want to match English language upper case letters other than S for the start of the second word:

$ grep '^S[[:alpha:]]*[[:lower:]][[:alpha:]]*, [ABCDEFGHIJKLMNOPQRTUVWXYZ][[:alpha:]]*[[:lower:]][[:alpha:]]*' file
Smith, Paul

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .