To match a string that only contains ASCII chars and has at least one ASCII letter, you may use
s.matches("[\\p{ASCII}&&[^A-Za-z]]*[A-Za-z]\\p{ASCII}*")
See this Java demo
If you do not want to allow control chars in the input, use a variation of the pattern:
s.matches("[ -~&&[^A-Za-z]]*[A-Za-z][ -~]*")
See this Java demo.
Note that .matches
requires a full string match, hence, there is no need adding ^
and $
/ \z
anchors around the pattern.
Pattern details
[ -~&&[^A-Za-z]]*
- 0 or more printable ASCII chars except ASCII letters (&&[^...]
is a character class subtraction, it is here to make the pattern work faster, more efficiently)
[A-Za-z]
- an ASCII letter (=\p{Alpha}
)
[ -~]*
- 0 or more printable ASCII chars.
The \p{ASCII}
Unicode property class matches any ASCII chars.
Additional info
If you need to match a string with only certain script/alphabet letters and any other chars in a string, you may use
s.matches("\\P{L}*(?:[A-Za-z]\\P{L}*)+")
This [A-Za-z]
is for English, for Russian, you would use [а-яА-ЯёЁ]
.
Now, say you want to only match a string whose letters can only be Hebrew letters inside. Since \p{InHebrew}
contains all Hebrew script, not just letters, you would use an intersection of this class and a letter \p{L}
class, [\p{InHebrew}&&[\p{L}]]
:
str.matches("\\P{L}*(?:[\\p{InHebrew}&&[\\p{L}]]\\P{L}*)+")
^^^^^^^^^^^^^^^^^^^^^^^^^