Seite 4 von 4

Re: String in Text suchen und Satz ausgeben

Verfasst: Freitag 16. Dezember 2016, 17:33
von BlackJack
Eine Lösung in C und ein Transkript eines Textlaufes auf dem C64. :-D

Code: Alles auswählen

#include <assert.h>
#include <ctype.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>

#define BUFFER_SIZE 1000


void skip_whitespace(FILE *f)
{
    int c;

    do {
        c = fgetc(f);
    } while (isspace(c) && c != EOF);
    
    if (c != EOF) ungetc(c, f);
}


void read_sentence(FILE *f, char *buffer)
{
    unsigned int i;
    int c;

    for (i = 0; i < BUFFER_SIZE - 1; ++i) {
        c = fgetc(f);
        if (c == EOF) break;
        *buffer++ = c;
        if (c == '.') break;
    }
    *buffer = '\0';
    assert(c == EOF || c == '.');
}


bool contains_word(char *string, char *word)
{
    char *tmp;
    unsigned int start_index, end_index;

    tmp = strstr(string, word);
    if (!tmp) return false;
    start_index = tmp - string;
    end_index = start_index + strlen(word);
    return (start_index == 0
            || !isalnum(string[start_index - 1]))
        && (end_index == strlen(string - 1)
            || !isalnum(string[end_index]));
}


int main(void)
{
    FILE *f;
    char sentence[BUFFER_SIZE];
    char *filename = "winter's tale";

    f = fopen(filename, "r");
    if (!f) {
        printf("could not open '%s'\n", filename);
        return 1;
    }
    while (!feof(f)) {
        skip_whitespace(f);
        read_sentence(f, sentence);
        if (contains_word(sentence, "Luzifer")) {
            puts(sentence);
        }
    }
    fclose(f);
    return 0;
}
Testlauf:
[codebox=text file=Unbenannt.txt]LOAD"$",8

SEARCHING FOR $
LOADING
READY.
LIST

0 "TEST-DISK " 00 2A
36 "123456789012 PIC" PRG
21 "TEST" PRG
26 "WINTER'S TALE" SEQ
581 BLOCKS FREE.
READY.
LOAD"TEST",8,1

SEARCHING FOR TEST
LOADING $0801 $1BEE
READY.
RUN
Dort trifft er auf seinen Boss Luzifer,
den Richter.
Pearly ersucht Luzifer um die Genehmigun
g, ausnahmsweise Zugang zu einer Adresse
ausserhalb der Stadt zu bekommen: zu Be
verlys Haus am See; der hohe Richter Luz
ifer lehnt Pearlys Antrag ab.
Pearly hat mit Luzifer einen Deal ausgeh
andelt: Wenn er bereit sei, sich sterbli
ch zu machen, duerfe er Peter auch ausse
rhalb der Stadt verfolgen.

ready.[/code]

Re: String in Text suchen und Satz ausgeben

Verfasst: Freitag 16. Dezember 2016, 21:03
von nezzcarth
BlackJack hat geschrieben:@snafu: Schwierig. Insbesondere weil bei einigen Abkürzungen der Punkt gleichzeitig auch das Ende des Satzes sein kann. Wie bei ”usw.” wenn es am Satzende steht. [...] Natürliche Sprachen sind lustig. :-D
Wenn man es wirklich so elaboriert machen möchte, wäre der sauberere Weg m.M.n, einen Tokenizer für die die Zielsprache zu verwenden.
Das sieht dann z. B. so aus (https://www.linguistics.rub.de/~dipper/ ... nizer.html):

Code: Alles auswählen

$ cat text.txt                        
Am 23. Mai 1895 wird einem jungen Einwandererpaar auf Ellis Island die Einreise in die USA verweigert, weil beide an der Tuberkulose erkrankt sind. Als ihrem kleinen Sohn auch ohne sie die Einreise verweigert wird, beschließen sie, ihn in ein Modellsegelboot mit dem Namen Stadt der Gerechtigkeit zu setzen, in der Hoffnung, das Kind werde gefunden.
1916 ist das Kind zu einem Mann herangewachsen. Er nennt sich Dr. Peter Lake. Peter wurde von dem Gangsterboss Pearly Soames aufgezogen und verdient sich seinen Lebensunterhalt nun als Einbrecher und Dieb. Als Peter beschließt, Pearlys Bande und sein altes Leben zu verlassen, macht er sich seinen Ziehvater zum wütenden Gegner und wird von dessen Bande gejagt.

$ ./tokenize.pl -a abbrev.lex -y -t text.txt out.txt && cat out.txt
<?xml version="1.0" encoding="utf-8"?>
<text>
 <tok>Am</tok>
 <tok type='ord'>23.</tok>
 <tok>Mai</tok>
 <tok type='year'>1895</tok>
 <tok>wird</tok>
 <tok>einem</tok>
 <tok>jungen</tok>
 <tok>Einwandererpaar</tok>
 <tok>auf</tok>
 <tok>Ellis</tok>
 <tok>Island</tok>
 <tok>die</tok>
 <tok>Einreise</tok>
 <tok>in</tok>
 <tok>die</tok>
 <tok type='allCap'>USA</tok>
 <tok>verweigert</tok>
 <tok type='punc'>,</tok>
 <tok>weil</tok>
 <tok>beide</tok>
 <tok>an</tok>
 <tok>der</tok>
 <tok>Tuberkulose</tok>
 <tok>erkrankt</tok>
 <tok>sind</tok>
 <tok type='punc'>.</tok>
<sent_bound/>
 ...
 <tok>Er</tok>
 <tok>nennt</tok>
 <tok>sich</tok>
 <tok type='abbrev' source='listed'>Dr.</tok>
 <tok>Peter</tok>
 <tok>Lake</tok>
 <tok type='punc'>.</tok>
<sent_bound/>
...
NLTK und textblob bieten auch Tokenizer an.

Re: String in Text suchen und Satz ausgeben

Verfasst: Freitag 16. Dezember 2016, 22:03
von snafu
Vielleicht insbesondere mal textblob-de anschauen. Auszug aus der Beschreibung:

Code: Alles auswählen

>>> from textblob_de import TextBlobDE as TextBlob
>>> text = '''Heute ist der 3. Mai 2014 und Dr. Meier feiert seinen 43. Geburtstag.
Ich muss unbedingt daran denken, Mehl, usw. für einen Kuchen einzukaufen. Aber leider
habe ich nur noch EUR 3.50 in meiner Brieftasche.'''
>>> blob = TextBlob(text)
>>> blob.sentences
[Sentence("Heute ist der 3. Mai 2014 und Dr. Meier feiert seinen 43. Geburtstag."),
 Sentence("Ich muss unbedingt daran denken, Mehl, usw. für einen Kuchen einzukaufen."),
 Sentence("Aber leider habe ich nur noch EUR 3.50 in meiner Brieftasche.")]
>>> blob.tokens
WordList(['Heute', 'ist', 'der', '3.', 'Mai', ...]

Re: String in Text suchen und Satz ausgeben

Verfasst: Freitag 16. Dezember 2016, 22:19
von kbr
snafu hat geschrieben:Vielleicht insbesondere mal textblob-de anschauen.
Wie sich zeigt, ist das extrahieren von Sätzen aus komplexeren Texten alles andere als trivial. Vielleicht ist zumindest das ein gewisser Trost für den OP.

Re: String in Text suchen und Satz ausgeben

Verfasst: Freitag 16. Dezember 2016, 22:43
von snafu
Habe es mal mit einem schnell zusammengeschriebenen Beispieltext gefüttert, wo wörtliche Rede in verschiedenen Formen enthalten ist. Ich bin kein Linguist, aber ich finde die Ergebnisse so wie ich es erwartet hätte. Wen's interessiert:

Code: Alles auswählen

In [12]: text = 'Er sagte: "Ich gehe ins Kino". Das tat er dann auch. "Das war eine großartige Idee", pflichtete Anna ihm bei als er wieder zuhause war. "Ich würde ja auch gerne. Aber ich muss lernen für die Prüfung." Das machte sie sehr traurig.'
In [13]: TextBlobDE(text).sentences
Out[13]:
[Sentence("Er sagte: "Ich gehe ins Kino"."),
 Sentence("Das tat er dann auch."),
 Sentence(""Das war eine großartige Idee", pflichtete Anna ihm bei als er wieder zuhause war."),
 Sentence(""Ich würde ja auch gerne."),
 Sentence("Aber ich muss lernen für die Prüfung.""),
 Sentence("Das machte sie sehr traurig.")]

In [14]: TextBlobDE(text).sentences[0].words
Out[14]: WordList(['Er', 'sagte', 'Ich', 'gehe', 'ins', 'Kino'])
Nur das Quoting ist eher ungewohnt und verwirrt den Python-Parser.