-3

I need a regex that gives me true when a letter exists in the input. I have tried if (formula.contains("[a-zA-Z]+") == true), but this does not seem to work.

Hi! I figured it out! formula.matches(".*[a-zA-Z].*") this worked!

Coder1235
  • 39
  • 5

3 Answers3

4

tl;dr

"123".codePoints().anyMatch( Character::isLetter  )

false

"123x".codePoints().anyMatch( Character::isLetter  )

true

"à la carte".codePoints().anyMatch( Character::isLetter  )

true

Unicode property isLetter

There are many more letters in Unicode than just a-z, A-Z.

The Character class provides a isLetter method to indicate if a given character is a letter as defined by the Unicode standard.

The String class offers the codePoints method to return a stream of int numbers. Each number represents a code point, the number that Unicode assigns to each of its 143,859 characters.

The Stream#anyMatch method runs a predicate against each element in the stream's sequence. This method stops when it finds the first hit, the first element in the stream for which the predicate returns true. This is call short-circuiting, meaning the work stops after the first found.

For our predicate test, we use that Character.isLetter method.

boolean containsLetter =
        "123"                                
                .codePoints()
                .anyMatch(
                        codePoint -> Character.isLetter( codePoint )
                );

We can shorten that by using a method reference with a pair of COLON characters.

boolean containsLetter =
        "123"                                    // `String` instance.
                .codePoints()                    // Returns an `IntStream`, a stream of `int` integers, one for each character’s Unicode code point number.
                .anyMatch(                       // Runs a predicate test against each element of the stream, stopping after the first to return `true`. 
                        Character :: isLetter    // Method reference for static method `Character.isLetter( int codePoint )`. Serves here as our `Predicate` test object for the `anyMatch` call.
                );                               // Returns `true` at the first letter found, or `false` if no letter found. 

Avoid char

Notice that we do not use the char type. That type is obsolete, unable to represent even half of the 143,859 characters defined by Unicode.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
3

String#contains does not treat its parameter as a RegEx.

You can use Matcher#find with the regex pattern, \p{L} which specifies any letter.

import java.util.regex.Pattern;
import java.util.stream.Stream;

public class Main {
    public static void main(String[] args) {
        //Test
        Stream.of(
                    "123",
                    "123a456",
                    "1a2b",
                    "@£$%^&"    
                ).forEach(s -> System.out.println(s + " => " + hasLetter(s)));
    }
    
    static boolean hasLetter(String s) {
        return Pattern.compile("\\p{L}").matcher(s).find();
    }
}

Output:

123 => false
123a456 => true
1a2b => true
@£$%^& => false
Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110
2

You'll need String#matches(regex) for this and a correct of course

if (formula.matches(".*[a-zA-Z].*")) {
    // do stuff
}

The regular expression hereabove means

.             Any character
 *            Zero or multiple times
  [a-zA-Z]    One letter in ranges a-z or A-Z
          .   Any character
           *  Zero or multiple times

Yassin Hajaj
  • 21,337
  • 9
  • 51
  • 89