Come posso prendere una lista di token (di numero variabile) e sapere cosa significa ogni token?

1

Devo leggere un documento di testo con dati formattati come segue: (un paio di esempi)

07 M W F 1400 1450 C 2004
M W F 0900 1030 EN 2036
06 M T R 1300 1350 EN 1003
17 T R 0900 1015 EN 1052

Il problema che sto avendo è, una volta dividere queste stringhe con .split(" ", -1) , ottengo un numero diverso di token per molti di essi, e la posizione della differenza varia nelle prime due "sezioni".

La prima parte della stringa dovrebbe rappresentare un codice di pianificazione. È facoltativo, come si può vedere dal fatto che manchi nella seconda riga. La seconda area descrive i giorni della settimana in cui si applica questo programma. Potrebbero essere ovunque da uno a cinque giorni, ma in questi esempi ce ne sono solo 2 o 3. Quindi il resto è praticamente statico: ora di inizio, ora di fine, codice di costruzione e numero di camera.

Quello che devo fare è costruire più oggetti per questo programma sulla base di queste informazioni (un oggetto per ogni giorno), e non sono sicuro di come procedere. Come posso dire, durante l'iterazione sulla serie di token, cosa rappresenta ciascun token? Ho pensato di utilizzare un'istruzione switch , ma funzionerebbe solo per i giorni, poiché ce ne sono 5.

Quello che segue è il codice che (a titolo provvisorio) prevede di utilizzare per questo oggetto.

public class TimeSlot {

  private Day day;
  private int startTime;    // # of minutes after midnight
  private int endTime;
  private Room room;
  private String slot;

  /**
   * Default constructor. Create an instance of TimeSlot.
   * @param day   day of the week
   * @param start start time of lecture represented as minutes after midnight
   * @param end   end time of lecture represented as minutes after midnight
   * @param room  room the class takes place in
   */
  public TimeSlot(String slot, Day day, int start, int end, Room room) {
    this.slot = slot;
    this.day = day;
    this.startTime = start;
    this.endTime = end;
    this.room = room;
  }
}

enum Day {
  MONDAY,
  TUESDAY,
  WEDNESDAY,
  THURSDAY,
  FRIDAY,
  SATURDAY,
  SUNDAY;
}

public class Room {

  private String buildingCode;
  private String roomNumber;

  public Room(String building, String room) {
    this.buildingCode = building;
    this.roomNumber = room;
  }

  public String buildingCode() {
    return buildingCode;
  }

  public String roomNumber() {
    return roomNumber;
  }

}
    
posta agent154 16.01.2014 - 17:10
fonte

4 risposte

4

Per quanto le persone a volte si lamentino delle espressioni regolari, questo è uno scenario perfetto per utilizzarle. Non ho familiarità con la sintassi per Java ( ma ecco un riferimento ), ma posso dire tu che vuoi il modello:

(\d+ )?([MTWRF] )+(\d+) (\d+) (\w+) (\d+)

Puoi testarlo qui .

Passo dopo passo, questo significa:

  • (\d+ )? - Se esistono, acquisisci qualsiasi numero di cifre seguito da uno spazio.
  • ([MTWRF] )+ - Cattura una lettera dal set MTWRF seguito da uno spazio, tutte le volte che succede (ma almeno una volta).
    • Se vuoi applicare la regola 1-5, sostituisci + con {1,5} , quindi diventa ([MTWRF] ){1,5} .
    • Se vuoi includere sabato e domenica, aggiungi S e U all'interno del blocco [] (l'ordine non ha importanza), quindi diventerebbe ([UMTWRFS] )+ .
  • (\d+) - Cattura una serie di cifre. Se si desidera applicare quattro cifre, sostituire + con {4} in modo che diventi (\d{4}) , o semplicemente inserire quattro \d caratteri per rendere (\d\d\d\d) .
  • (\d+) - Cattura un'altra serie di cifre. Vedi sopra per le modifiche.
  • (\w+) - Cattura una serie di lettere
  • (\d+) - Cattura un'ultima serie di cifre. Vedi sopra per le modifiche.

È quindi possibile accedere a ciascuna cattura, se la prima non corrisponde, dovrebbe essere vuota. Se il secondo corrisponde a più lettere, puoi semplicemente ottenerle dividendo in spazi. Tutti gli altri non hanno nemmeno spazi vaganti di cui preoccuparsi.

    
risposta data 16.01.2014 - 18:06
fonte
0

Il primo passo è sparare alla persona che ha scelto di raccogliere i dati in quel modo: un numero variabile di campi senza identificatori è piuttosto noioso. Inoltre, il giorno della settimana è ridicolo per un'app di pianificazione della stanza, a meno che non lo si pianifichi per mesi alla volta (con qualche tipo di data di scadenza predefinita?). Questo sarebbe un non-problema se hai memorizzato le date.

In questo caso, tuttavia, puoi probabilmente analizzare gli argomenti e capire dove ti trovi se vedi o meno un numero intero nel campo dati. Da quello che hai detto sembra che i dati si rompano abbastanza chiaramente:

La prima posizione è un numero intero o un carattere (stringa? Giovedì "Th"?). Dopo di che hai un numero variabile di non interi fino a quando non arrivi all'ora di inizio, quindi hai l'ora di fine, poi la costruzione, poi la stanza. Dovrai comunque saperlo (poiché Java è staticamente / strongmente digitato), quindi potrebbe anche farne uso.

    
risposta data 16.01.2014 - 17:24
fonte
0

Potresti provare a processare i token dalla parte posteriore poiché questi, secondo te, hanno un formato coerente. Quindi, quando si passa alla parte variabile, è necessario assicurarsi che i giorni della settimana siano validi e, in caso contrario, è il codice di pianificazione. Certo, controlla che sia anche numerico.

    
risposta data 16.01.2014 - 18:33
fonte
0

Potresti prendere in considerazione l'utilizzo di Scanner anziché di String e split (). Sembra che l'uso dei vari metodi hasNext () e next () di Scanner consenta di configurare la logica in base alle proprie esigenze e verificare se la voce successiva nel file è un numero intero oppure no, o corrisponde a un determinato modello come hasNext (" M "). Il delimitatore predefinito dello scanner è un carattere di spazio bianco, quindi dovrebbe funzionare correttamente per il file di input, sebbene sia possibile anche impostare il delimitatore su qualsiasi espressione regolare di espressioni regolari utilizzando useDelimeter ().

    
risposta data 17.01.2014 - 02:06
fonte

Leggi altre domande sui tag