Почему мой матч не работает? - PullRequest
1 голос
/ 24 августа 2009

Я передаю строку в метод синтаксического анализа песни, и она не работает, и я не могу понять, почему. Каждая вещь возвращает ноль или 0.

Мой метод парсера

 public static Song parseSong(String songString){
  Map<String, String> songMap = new HashMap<String, String>();
  Pattern pattern = Pattern.compile(".*<key>(.+)</key><(.+)>(.+)</.+>.*\n");
  Scanner scanner = new Scanner(songString);
  if(scanner.hasNext(pattern))
  {
     String line = scanner.next(pattern);
     Matcher matcher = pattern.matcher(line);
     MatchResult result = matcher.toMatchResult();
     songMap.put(result.group(1), result.group(3));
  }
  int count = 0, rating = 0;
  try{
     count = Integer.parseInt(songMap.get("Play Count"));
  }
  catch(Exception e)
  {
     //bury this for now will handle when rest is working
  }
  try{
     rating = Integer.parseInt(songMap.get("Rating"));
  }
  catch(Exception e)
  {
     //bury this for now will handle when rest is working
  }
  return new Song(songMap.get("Name"), songMap.get("Artist"), songMap.get("Album"),
        songMap.get("Genre"), count, rating, songMap.get("Location"));

}

      String songString = "<key>Track ID</key><integer>160</integer>\n"+
     "<key>Name</key><string>Ashley</string>\n"+
    " <key>Artist</key><string>Escape the Fate</string>\n"+
    " <key>Composer</key><string>Luca Gusella</string>\n"+
    " <key>Album</key><string>This War Is Ours</string>\n"+
  "   <key>Genre</key><string>Metal</string>\n"+
     "<key>Kind</key><string>AAC audio file</string>\n"+
  "  <key>Size</key><integer>7968219</integer>\n"+
   "  <key>Total Time</key><integer>246503</integer>\n"+
  "   <key>Track Number</key><integer>17</integer>\n"+
   "  <key>Year</key><integer>2005</integer>\n"+
   "  <key>Date Modified</key><date>2009-07-27T01:17:29Z</date>\n"+
    " <key>Date Added</key><date>2009-07-27T01:17:00Z</date>\n"+
    "<key>Play Count</key><integer>150</integer>\n"+
    " <key>Bit Rate</key><integer>256</integer>\n"+
    " <key>Sample Rate</key><integer>44100</integer>\n"+
    " <key>Comments</key><string>\"Amanda\" performed by Aisha Duo from the CD Quiet Songs, courtesy of Obliq Sound.  Written by Luca Gusella, published by Editions ObliqMusic (GEMA).  All Rights Reserved.  Used by Permission. </string>\n"+
    " <key>Skip Count</key><integer>1</integer>\n"+
    " <key>Skip Date</key><date>2009-07-27T01:46:32Z</date>\n"+
    " <key>Artwork Count</key><integer>1</integer>\n"+
    " <key>Persistent ID</key><string>A4D6F35FE9F41B58</string>\n"+
    " <key>Track Type</key><string>File</string>\n"+
    " <key>Location</key><string>file://localhost/C:/Documents%20and%20Settings/MB24244/Desktop/music/07%20Knees.m4a</string>\n"+
     "<key>File Folder Count</key><integer>4</integer>\n"+
     "afgjdhfshsgsughghanoise\n"+
     "<key>Library Folder Count</key><integer>1</integer>\n"+
     "<key>Rating</key><integer>100</integer>";

Может ли кто-нибудь помочь объяснить, что не так с моим подходом и почему группы не работают (именно в этом и заключается проблема)

Ответы [ 5 ]

7 голосов
/ 24 августа 2009

Почему бы не использовать синтаксический анализатор XML до синтаксический анализ XML ?

Несмотря на то, что, глядя на пример XML, он не так хорош, так как он моделирует map вместо моделирования <song>

Глядя на свое регулярное выражение, почему вы ищете строку, заканчивающуюся \n. Похоже, что вы сопоставляете каждую строку по очереди, и я не верю, что они будут содержать символ новой строки.

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

    Map<String, String> songMap = new HashMap<String, String>();

    Pattern pattern = Pattern
            .compile(".*<key>(.+)</key><(.+)>(.+)</.+>.*");

    String[] lines = songString.split("\n");

    for (String line : lines) {
        Matcher matcher = pattern.matcher(line);
        if (matcher.matches()) {
            songMap.put(matcher.group(1), matcher.group(3));
        }
    }

Возможно, вы также можете настроить его на работу со сканером.

1 голос
/ 24 августа 2009
if(scanner.hasNext(pattern))
{
   String line = scanner.next(pattern);
   Matcher matcher = pattern.matcher(line);
   matcher.toMatchResult();
   songMap.put(result.group(1), result.group(3));
}

Сопоставитель, созданный вами с помощью pattern.matcher (line), является совершенно новым объектом, который ничего не знает о совпадении, которое вы только что нашли со Сканером. То, что вы хотите, это:

MatchResult result = scanner.match();

Это регулярное выражение тоже нуждается в работе. Если каждая запись появляется в отдельной строке, вам не нужно добавлять ее с ".*" на любом конце, и вам не нужно совпадать с переводом строки. Кроме того, я предлагаю вам использовать ".+?" вместо ".+", где бы он ни появлялся. По этой причине читайте это .

1 голос
/ 24 августа 2009

Второе голосование за преобразование XML в действительный XML (один узел верхнего уровня), а затем использование синтаксического анализатора XML.

Но я бы заподозрил \ n в конце, не уверен, насколько это нравится библиотеке регулярных выражений Java?

0 голосов
/ 25 августа 2009

+ 1 к использованию. +?

Кроме того, я бы посоветовал не использовать шаблон в этом случае, так как у вас, кажется, есть довольно простой файл для анализа. Я мог бы: - разделить файл построчно - Использовать простые строковые методы для получения содержимого (кажется, что в вашем XML есть только 3 разных тега)

Если формат файла изменится и станет более сложным, я воспользуюсь настоящим XMLParser и просто пройду по дереву XML, чтобы получить то, что вам нужно:)

0 голосов
/ 24 августа 2009

Не пытайтесь написать синтаксический анализатор, если вы уже не знаете правила анализа этих файлов.

Регулярное выражение, которое вы написали, не следует очень многим правилам файлов XML.

Если вы впервые пишете регулярное выражение, вам, вероятно, следует попытаться научиться чему-то более простому для анализа. Возможно, даже простой формат файла, который вы создаете сами.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...