Найти первую букву в строке

Моя программа использует систему идентификации, которая требует 1-3 цифры перед буквой, а затем 1-3 цифры после символа. Например: 12a123 или 1b83 и т. д.

Я пытаюсь выяснить, как найти первое вхождение буквы в строке, чтобы я мог сохранить букву, поскольку она используется для операции между цифрами позже.

Спасибо :)


person MacJav    schedule 09.04.2018    source источник
comment
попробуйте регулярное выражение и найдите вторую группу в выражении?   -  person vikingsteve    schedule 09.04.2018
comment
найти первое вхождение символа в строку, используя indexOf. Это на самом деле то, что вы спрашиваете?   -  person khelwood    schedule 09.04.2018
comment
первый символ, используемый в строке, — myString.charAt(0);   -  person Stultuske    schedule 09.04.2018
comment
@Stultuske Он имеет в виду букву, хотя и называет ее персонажем.   -  person SeverityOne    schedule 09.04.2018


Ответы (5)


Просто прокрутите символы и выберите первый в диапазоне прописных/строчных букв от 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);
}
person Michael    schedule 09.04.2018
comment
Это не найдет неанглийские буквы, такие как é, æ и ς. Вероятно, лучше использовать Character.isLetter, как в ответе tommybee. - person Ole V.V.; 09.04.2018
comment
@ОлеВ.В. Намеренно так. Вероятно, лучше неточно. Мы просто не знаем. - person Michael; 09.04.2018
comment
Понятно, что знает только ОП. Сравнения >= и <= очень низкоуровневые. Если действительно запрашивается только английская буква, я предпочитаю Character.UnicodeBlock.of(character).equals(Character.UnicodeBlock.BASIC_LATIN) && Character.isLetter(character). Да, это длиннее, но более прямо выражает замысел и сообщает читателю, что мы рассмотрели неанглийские буквы. - person Ole V.V.; 09.04.2018
comment
@ОлеВ.В. Если вы хотите передать это, добавьте комментарий. - person Michael; 09.04.2018

Вы можете использовать регулярное выражение для этой задачи, например:

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

Разбивка:

  • \d{1,3} соответствует цифре (равной [0-9])
  • {1,3} Квантификатор — Соответствует от 1 до 3 раз, максимально возможное количество раз, возвращая по мере необходимости (жадный)
  • 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)
person Aniket Sahrawat    schedule 09.04.2018
comment
Вы заслуживаете тега Java. - person MS90; 24.03.2019

Могу предложить два решения:

Решение 1

Если вы используете Java 8, вы можете использовать:

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

Решение 2

Вы можете использовать replaceAll следующим образом:

String str = "12a123";
String firstCharacter  = str.replaceAll("\\d{1,3}([A-z])\\d{1,3}", "$1");//a
person YCF_L    schedule 09.04.2018
comment
Я думаю, что потоки с регулярным выражением - это немного накладных расходов. - person ; 09.04.2018
comment
хм @roundО, что ты имел в виду! - person YCF_L; 09.04.2018
comment
Преимущество решения replaceAll состоит в том, что оно обеспечивает небольшую проверку строки. В частности, если вы добавите ^ в начале и $ в конце регулярного выражения. - person Ole V.V.; 09.04.2018
comment
Спасибо @OleV.V. но две привязки не нужны в регулярном выражении Java, почему, потому что replaceAll используйте сопоставитель, поэтому оба не нужны, для более подробной информации прочитайте этот Является ли регулярное выражение в Java привязанным по умолчанию с помощью обоих ^ и символ $? :) - person YCF_L; 09.04.2018

Используйте метод isLetter класса символов Java.

Это выглядит как;

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));
    }
}
person tommybee    schedule 09.04.2018
comment
Character.isLetter вернет true для символов с диакритическими знаками (например, é). Может быть желанным, может не быть. - person Michael; 09.04.2018
comment
@Майкл, я бы сказал, желательно для большинства целей. Буква с диакритическим знаком остается буквой. ОП лучше знает, желательно ли это в его/ее контексте. - person Ole V.V.; 09.04.2018

Этот похож на Аникет.

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"));
        }
    }
}
person Sunil    schedule 09.04.2018