Проблема с сканированием каждого символа в java

#java #for-loop #token

Вопрос:

поэтому я делаю сканер токенов, который сканирует текстовый файл и идентифицирует каждый из токенов в этом текстовом файле либо как идентификатор, либо как номер, либо как символ. Вот мой код:

 import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


public class Main {

public static void main(String args[]) throws FileNotFoundException {

//Create a pattern to see if it matches the string
String IDENTIFIER = "([a-z]|[A-Z])([a-z]|[A-Z]|[0-9])*";
String SYMBOL = "\*|\ |\(|\)|\/|\-";
String NUMBER = "\d ";

//Scan the text input file
Scanner input = new Scanner(new File("input.txt"));

while(input.hasNext()){
  String token = input.nextLine();
  String ip[] = token.split("\s ");
  System.out.println("Line: "   token);

  for(int i = 0 ; i< ip.length; i  ){
    for(int j = 0; j <ip[i].length(); j  ){
      if(ip[i].substring(0,ip[i].length()).matches(IDENTIFIER)){
            System.out.println(ip[i]   " : IDENTIFIER");
      }else if(ip[i].substring(0,ip[i].length()).matches(NUMBER)){
            System.out.println(ip[i]  " : NUMBER");
      }else if(ip[i].substring(0,ip[i].length()).matches(SYMBOL)){
            System.out.println(ip[i]   " : SYMBOL");
      }else 
            System.out.println("ERROR READING"   "'"   ip[i]   "'");
    }
  }
}
 

}
}

В цикле double for внешний просматривает каждый отдельный элемент массива, а внутренний просматривает каждый отдельный символ элемента в массиве. Но, похоже, это не работает. Допустим, входной файл: 34 89amp; — x * y23 / 56n34

вывод, который я получил: Строка: 34 89amp; — x * y23 / 56n34 34 : НОМЕР 34 : НОМЕР

  • : ОШИБКА СЧИТЫВАНИЯ СИМВОЛОВ’89amp;’ ОШИБКА СЧИТЫВАНИЯ’89amp;’ ОШИБКА СЧИТЫВАНИЯ’89amp;’
  • : СИМВОЛ x : ИДЕНТИФИКАТОР
  • : СИМВОЛ y23 : ИДЕНТИФИКАТОР y23 : ИДЕНТИФИКАТОР y23 : ИДЕНТИФИКАТОР / : СИМВОЛ ОШИБКА СЧИТЫВАНИЯ’56n34′ ОШИБКА СЧИТЫВАНИЯ’56n34′ ОШИБКА СЧИТЫВАНИЯ’56n34′ ОШИБКА СЧИТЫВАНИЯ’56n34′ ОШИБКА СЧИТЫВАНИЯ’56n34’ОШИБКА СЧИТЫВАНИЯ’56n34′

выход, который я ожидал: Строка: 34 89amp; — x * y23 / 56n34 34 : НОМЕР

  • : СИМВОЛ 89: ОШИБКА СЧИТЫВАНИЯ НОМЕРА’amp;’
  • : СИМВОЛ x : ИДЕНТИФИКАТОР
  • : СИМВОЛ y23 : ИДЕНТИФИКАТОР / : СИМВОЛ 56: ЧИСЛО n34: ИДЕНТИФИКАТОР

Любой знает, в чем проблема, в чем мой цикл for. Спасибо

Комментарии:

1. Переменная j не используется внутри цикла. Для чего нужна внутренняя петля?

2. как я уже упоминал, внутренний цикл предназначен для сканирования каждого символа в ip[i]: Например, в этом случае: ip[0] будет 34. Внутренний цикл будет сканировать 34 от j до длины, равной 2.

3. Пожалуйста, проясните вашу конкретную проблему или предоставьте дополнительные сведения, чтобы точно указать, что вам нужно. Поскольку это написано в настоящее время, трудно точно сказать, о чем вы просите.

Ответ №1:

Этот альтернативный подход может быть близок к выполнению работы.

Для работы с каждым символом используйте целые числа кодовых точек.

Консорциум Unicode идентифицировал более 140 000 символов на разных языках, а также символы и смайлики. Каждому из них Консорциум на постоянной основе присвоил конкретный номер в качестве идентификатора. Это число известно как кодовая точка.

Избегайте char и его класса-оболочки Character для представления отдельных символов. char Тип в Java является устаревшим, по сути, сломанным, неспособным представлять большинство символов.

 package work.basil.text;

public class App6
{
    public static void main ( String[] args )
    {
        App6 app = new App6();
        app.demo();
    }

    private void demo ()
    {
        String input = "A1😷 ";
        input.codePoints().forEach(
                App6 :: report
        );
    }

    public static void report ( int codePoint )
    {
        if ( Character.isJavaIdentifierPart( codePoint ) )
        {
            System.out.println( "Java Identifier part: "   Character.toString( codePoint ) );
        } else if ( Character.isDigit( codePoint ) )
        {
            System.out.println( "Digit: "   Character.toString( codePoint ) );
        } else if ( Character.getType( codePoint ) == Character.MATH_SYMBOL )
        {
            System.out.println( "Math symbol: "   Character.toString( codePoint ) );
        } else
        {
            System.out.println( "Something else: "   Character.toString( codePoint )   " (code point "   codePoint   ")." );
        }
    }
}
 

Когда бегут.

 Java Identifier part: A
Java Identifier part: 1
Something else: 😷 (code point 128567).
Math symbol:  
 

Комментарии:

1. Ср, я немного не уверен в точке ввода кода. Вы можете объяснить, что это такое? Спасибо

2. @Yang Вы читали страницу Википедии, на которую я ссылался? Я добавлю резюме к ответу.

3. Спасибо, я прочитал это, но есть ли способ проверить, соответствует ли оно определенному регулярному выражению, поскольку JavaIdentifierPart и математический символ все встроены в библиотеку для java, которая не включает все символы, которые я хочу проверить

4. @Yang Я не фанат регулярных выражений. Чтобы определить свой собственный набор символов для использования при проверке, создайте массив int или List (или NavigableSet ) Integer объектов. Заполните кодовую точку каждого символа, на который вы хотите нацелиться. Найдите в этом массиве/списке/наборе совпадение.