2010-02-02 14 views
6

Sono sicuro che la gente si farà una bella risata da questo, ma per la vita di me non riesco a trovare un separatore che indicherà quando un nuovo paragrafo è iniziato in una stringa di testo. Parola e linea? Facile, ma il paragrafo sembra essere molto più difficile da trovare. Ho provato due interruzioni di riga di fila, la rappresentazione Unicode dell'interruzione di paragrafo e interruzione di riga, senza fortuna.Quale carattere può essere utilizzato per analizzare paragrafi con Java?

EDIT: Mi scuso per la vaghezza della mia domanda iniziale. Per rispondere ad alcune domande, si tratta di un file di testo di base creato originariamente su Windows. Sto testando del codice per aprire e analizzare il suo contenuto con Blackberry JDE 4.5 usando il plugin RIM Eclipse. Mentre la sorgente del file sarà Windows (almeno per il prossimo futuro) e sarà un testo di base, non ho alcun controllo su come vengono creati (è una fonte di terze parti che non ho accesso al modo in cui è stata creata)

+0

Qual è il tuo pubblico per questo personaggio? – bmargulies

+0

Che aspetto ha il testo che stai cercando di analizzare? Esistono dozzine di modi diversi per formattare le interruzioni di paragrafo. – jball

+0

Mi piace usare la stringa "I'm a new paragraph" come delimitatore. Usa tutto ciò che non interferisce con altre cose. –

risposta

5

Non esiste un carattere di interruzione di paragrafo nell'uso comune.

Si potrebbe essere in grado di farla franca partendo dal presupposto che due o più interruzioni di riga consecutive (con spazi bianchi opzionali) indicano un'interruzione di paragrafo. Ma ci sono numerose eccezioni a questa "regola". Ad esempio, quando un paragrafo

  • è interrotta da una figura di galleggiamento, o
  • contiene punti elenco

e poi continua su ... come questo. Per quel tipo di cose, probabilmente non c'è soluzione.

MODIFICA per commento di @ Aiden qui sotto. (Ora è chiaro che questo non è rilevante per l'OP, ma potrebbe essere rilevante per gli altri che trovano la domanda tramite Google, ecc.)

Invece di provare a decodificare i paragrafi dal testo, forse dovresti considerare di specificare che il tuo input dovrebbe essere in (per esempio) la sintassi Markdown; cioè come supportato da StackOverflow. Lo Markdown Wiki include collegamenti a implementazioni di parser markdown in molte lingue, incluso Java.

(Questo presuppone che un certo controllo sul formato di input del testo che si sta tentando di analizzare in paragrafi, eccetera.)

+0

Forse ha bisogno di puntare nella direzione di un parser di markdown Java di base? –

3

E 'possibile che invece sulla linea di alimentazione è necessario cercare un CR LF sequenza (\ r \ n) - ovviamente la risposta dipenderebbe dal formato del testo.

2
String lineSeparator = System.getProperty("line.separator"); 

Restituisce il separatore di riga predefinito della piattaforma.

Pertanto, ad es. il seguente dovrebbe funzionare:

String[] paragraphs = text.split(lineSeparator); 
+0

Funzionerà solo se line.separator viene utilizzato solo per i nuovi paragrafi, il che non è necessariamente il caso. – sleske

+0

Presuppone inoltre che il sistema che genera il testo utilizza lo stesso separatore del sistema che esegue il codice. –

+0

Completamente corretto. L'OP deve chiarire di più il requisito funzionale e il problema reale. La domanda vaga era tuttavia abbastanza riconoscibile da indurmi a fornire questa risposta. – BalusC

2

Suppongo che tu abbia un file di testo e non un documento complesso come MS-Word o RTF.

Il concetto di paragrafo nel documento di testo non è ben definito. La maggior parte dei casi in cui il nuovo paragrafo verrà riconosciuto dal fatto che quando si apre un documento nell'editor di testo, si vedrà il prossimo set di testo che inizia sulla riga successiva.

Ci sono due caratteri speciali vale a dire. new-line (LF - '\n') e carriage-return (CR - '\r') che fa iniziare il testo sulla riga successiva. Quale carattere è usato per la prossima linea dipende dal sistema operativo che usi.Inoltre, a volte una combinazione di entrambi viene utilizzata anche come CRLF ('\r\n').

In java è possibile determinare il carattere o il set di caratteri utilizzati per eseguire la sepa- razione di linee/paragrafi utilizzando System.getProperty("line.separator");. Ma questo introduce un nuovo problema. Cosa succede se si crea un file di testo in MS Windows e poi lo si apre in Unix? Line seprator in file di testo in questo caso è quella di windows, ma java è in esecuzione su unix.

.

La mia raccomandazione è:

se la lunghezza del testo (docuemnt) è zero, allora paragrafi = 0.

se la lunghezza del testo (docuemnt) NON è zero, allora

  • Considerare '\n' e '\r' come riga interruzione caratteri.
  • Analizza il testo per la riga sopra riportata caratteri.
  • Qualsiasi carattere di interruzione di riga continua in qualsiasi ordine deve essere considerato come uno interruzione di paragrafo.
  • Numero di paragrafi = 1 + (conteggio di interruzioni di paragrafo)

nota, eccezioni a punta da Stephen vale ancora qui pure.

.

public class ParagraphTest { 

    public static void main(String[] args) { 
     String document = 
        "Hello world.\n" + 
        "This is line 2.\n\r" + 
        "Line 3 here.\r" + 
        "Yet another line 4.\n\r\n\r" + 
        "Few more lines 5.\r"; 
     printParaCount(document); 
    } 

    public static void printParaCount(String document) { 
     String lineBreakCharacters = "\r\n"; 
     StringTokenizer st = new StringTokenizer(
        document, lineBreakCharacters); 
     System.out.println("ParaCount: " + st.countTokens()); 
    } 

} 

uscita

ParaCount: 5 
3

paragrafi in documenti di testo sono di solito separate da due o più separatori di linea. Un separatore di riga può essere un linefeed (\n), un carriage-return (\r) o un carriage-return seguito da un linefeed (\r\n). Questi tre tipi di separatori sono in genere associati ai sistemi operativi, ma qualsiasi applicazione è libera di scrivere testo utilizzando qualsiasi tipo di separatore di riga. In effetti, il testo che è stato assemblato da fonti diverse (come una pagina web) potrebbe contenere due o più tipi di separatori. Quando la tua app legge il testo, indipendentemente dalla piattaforma su cui è in esecuzione, dovrebbe sempre verificare tutti e tre i tipi di separatore di riga.

BufferedReader#readLine() lo fa, ma ovviamente legge solo una riga alla volta. La prosa semplice verrà di solito restituita come sequenza alternata di linee non vuote che rappresentano i paragrafi e linee vuote che rappresentano gli spazi tra di esse. Ma non contare su di esso; guardare più righe vuote e tenere presente che le righe "vuote" potrebbero infatti contenere caratteri di spazi bianchi come lo spazio (\u0020) e il TAB (\u0009).

Se si sceglie di non andare con uno BufferedReader, potrebbe essere necessario scrivere il codice di rilevamento da zero. Java ME non include il supporto regex, quindi split() e java.util.Scanner non sono disponibili; e StringTokenizer non fa distinzione tra un singolo carattere di delimitazione e molti di seguito a meno che non si usi l'opzione returnDelims.Quindi restituisce i delimitatori un carattere alla volta, quindi devi ancora scrivere il tuo codice per capire che tipo di separatore stai guardando, se esiste.

2

In primo luogo, la soluzione migliore sarebbe definire un paragrafo. Che si tratti di un'interruzione di riga, di una interruzione di linea doppia o di un'interruzione di riga seguita da una scheda. Supponendo di non avere alcun controllo sull'input e di voler determinare il numero di paragrafi in vari campioni di testo, ognuna di queste situazioni potrebbe esistere. Inoltre, potrebbero essere utilizzati per lo stesso scopo all'interno dello stesso documento. Pertanto, per questo è necessaria un'analisi e tenere presente che non sarà sempre accurato al 100%.

Inizia inizializzando i vari possibili interruzioni di paragrafo:

  • "\ r"
  • "\ n \ r"
  • "\ n"
  • System.getProperty ("line.seperator ")

e tutti questi, ma due volte e tutte quelle varianti con un carattere di tabulazione aggiuntivo ('\ t') alla fine.

Il modo inefficiente per fare ciò sarebbe caricare l'input in una stringa e quindi chiamare buffer.split().length per determinare quanti paragrafi c'erano. Il modo efficiente e scalabile sarebbe quello di usare un flusso e andare oltre l'input, tenendo conto di quanto è lungo il paragrafo, e buttare quei paragrafi al di sotto di una determinata "soglia". Un algoritmo più avanzato potrebbe anche cambiare quello che considera un paragrafo dopo che incontra un interruttore nel modo in cui vengono gestite le interruzioni di riga (diverse linee molto brevi o diverse molto lunghe, ad esempio).

E tutto ciò presuppone che si tratti di testo non formattato senza titoli di sezioni, ecc. Si tratta di chiedere il numero di paragrafi in un particolare testo è come chiedere quante settimane sono in un anno. Non è esattamente il 52, ma è lì intorno.

Problemi correlati