1

My program uses an ID system that requires 1-3 digits before a letter then 1-3 digits following the character. For example: 12a123 or 1b83, etc.

What I'm trying to find out is how to find the first occurrence of a letter in the string so I can store the letter as it’s used for an operation between the digits later.

Thanks :)

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
MacDev
  • 25
  • 5

5 Answers5

3

I can suggest two solutions :

Soution 1

If you are using Java 8 you can use :

String str = "12a123";
char firstCharacter = (char) str.chars()
        .filter(c -> String.valueOf((char) c).matches("[a-zA-Z]"))
        .findFirst()
        .orElseThrow(() -> new Exception("No character exist"));//a

Soution 2

You can use replaceAll like this :

String str = "12a123";
String firstCharacter  = str.replaceAll("\\d{1,3}([A-z])\\d{1,3}", "$1");//a
Youcef LAIDANI
  • 55,661
  • 15
  • 90
  • 140
  • 2
    I think streams with regex is a bit of overhead. –  Apr 09 '18 at 08:32
  • hmm @roundAbout what did you mean! – Youcef LAIDANI Apr 09 '18 at 08:39
  • The `replaceAll` solution has the advantage of providing a bit of validation of the string. In particular if you add `^` at the front and `$` at the back of the regular expression. – Ole V.V. Apr 09 '18 at 09:03
  • Thank you @OleV.V. but the two anchors are not necessary in the Java regex, why because [replaceAll](http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/lang/String.java#String.replaceAll%28java.lang.String%2Cjava.lang.String%29) use matcher so both are not necessary for more details read this [Is regex in Java anchored by default with both a ^ and $ character?](https://stackoverflow.com/questions/1894624/is-regex-in-java-anchored-by-default-with-both-a-and-character) :) – Youcef LAIDANI Apr 09 '18 at 09:21
3

Just loop through the characters and grab the first one in the range upper/lowercase A-Z.

public char getCharacter(final String code)
{
    for (char character : code.toCharArray())
    {
        if (   (character >= 'a' && character <= 'z')
            || (character >= 'A' && character <= 'Z'))
        {
            return character;
        }
    }
    throw new RuntimeException("No character in ID: " + code);
}
Michael
  • 41,989
  • 11
  • 82
  • 128
  • 1
    This will not find a non-English letter like `é`, `æ` and `ς`. Probably better to use `Character.isLetter` as in [tommybee’s anwer](https://stackoverflow.com/a/49728553/5772882). – Ole V.V. Apr 09 '18 at 08:54
  • @OleV.V. Deliberately so. "Probably better" is inaccurate. We simply don't know. – Michael Apr 09 '18 at 08:56
  • Obviously only the OP knows. The `>=` and `<=` comparisons are very low-level. If indeed an English letter only is asked for, I prefer `Character.UnicodeBlock.of(character).equals(Character.UnicodeBlock.BASIC_LATIN) && Character.isLetter(character)`. Yes, it‘s longer, but more directly expresses the intent and tells the reader that we have considered non-English letters. – Ole V.V. Apr 09 '18 at 12:48
  • @OleV.V. If you want to convey that, add a comment. – Michael Apr 09 '18 at 12:53
2

You can use regex for this task, eg:

System.out.println("12a123".replaceAll("\\d{1,3}([A-z])\\d{1,3}", "$1"));

Breakdown:

  • \d{1,3} matches a digit (equal to [0-9])
  • {1,3} Quantifier — Matches between 1 and 3 times, as many times as possible, giving back as needed (greedy)
  • 1st Capturing Group ([A-z])
    • Match a single character present in the list below [A-z] A-z a single character in the range between A (index 65) and z (index 122) (case sensitive)
Aniket Sahrawat
  • 12,410
  • 3
  • 41
  • 67
1

Use isLetter method of the Java's Character class.

It looks like;

public class CharacterTest {

    private static Character getFirstCharInString(final String candid)
    {
        int found = 0;

        char [] candids = candid.toCharArray();

        for(found = 0; found < candids.length; found++)
        {
            if(Character.isLetter(candids[found])) break;
        }

        return new Character(candids[found]);
    }

    public static void main(String[] args) {

        String ids = "12a123";
        String ids2 = "1b83";

        System.out.println(getFirstCharInString(ids));
        System.out.println(getFirstCharInString(ids2));
    }
}
tommybee
  • 2,409
  • 1
  • 20
  • 23
  • 1
    `Character.isLetter` will return true for characters with accents (e.g. `é`). May be desirable, may not be. – Michael Apr 09 '18 at 08:33
  • @Michael I’d say desirable for most purposes. A letter with a diacritical mark is still a letter. The OP knows best whether it’s desired in his/her context. – Ole V.V. Apr 09 '18 at 08:51
1

This one is on the similar lines as Aniket.

public class ExampleCode 
{
    public static void main(String[] args) 
    {
        String[] input = { "12a234", "1s324" };
        String[] operations = new String[input.length];

        for (int i=0; i < input.length; i++) 
        {
            operations[i] = token.replaceAll("\\d{1,3}([A-z])\\d{1,3}", "$1"));
        }
    }
}
Sunil
  • 136
  • 2
  • 12