J'ai un fichier texte sauvage et fou, dont la tête ressemble à ceci:
2016-07-01 02:50:35 <name redacted> hey 2016-07-01 02:51:26 <name redacted> waiting for plane to Edinburgh 2016-07-01 02:51:45 <name redacted> thinking about my boo 2016-07-01 02:52:07 <name reda> nothing crappy has happened, not really 2016-07-01 02:52:20 <name redac> plane went by pretty fast, didn't sleep 2016-07-01 02:54:08 <name r> no idea what time it is or where I am really 2016-07-01 02:54:17 <name redacted> just know it's london 2016-07-01 02:56:44 <name redacted> you are probably asleep 2016-07-01 02:58:45 <name redacted> I hope fish was fishy in a good eay 2016-07-01 02:58:56 <name redacted> ð 2016-07-01 02:59:34 <name redacted> ððð 2016-07-01 03:02:48 <name > British security is a little more rigorous...
Cela continue pendant un moment. C'est un gros dossier. Mais j'ai l'impression que cela va être difficile à annoter avec la bibliothèque ou le package coreNLP. Je fais du traitement du langage naturel. En d'autres termes, je suis curieux de savoir comment je raser, disons, au moins les dates, sinon les dates et les noms.
Mais j'imagine que j'aurais besoin des noms, car, finalement, j'aimerais pouvoir être comme, cette personne l'a dit 50 fois, alors que cette personne l'a dit 75 fois, et ainsi de suite, mais c'est probablement un peu en avance sur moi-même.
Cela nécessiterait-il une expression régulière? Je travaille en R.
Je n'ai encore rien essayé, car je ne sais pas par où commencer. Comment écrire un code dans R qui ne lirait sélectivement que le texte? les phrases et les phrases bien composées?
4 Réponses :
Cela n'a peut-être pas besoin d'une expression, mais si vous souhaitez le faire, cette expression pourrait vous aider simplement à cela:
const regex = /(.*)(\s<name.*)/gm; const str = `2016-07-01 02:50:35 <name redacted> hey 2016-07-01 02:51:26 <name redacted> waiting for plane to Edinburgh 2016-07-01 02:51:45 <name redacted> thinking about my boo 2016-07-01 02:52:07 <name reda> nothing crappy has happened, not really 2016-07-01 02:52:20 <name redac> plane went by pretty fast, didn't sleep 2016-07-01 02:54:08 <name r> no idea what time it is or where I am really 2016-07-01 02:54:17 <name redacted> just know it's london 2016-07-01 02:56:44 <name redacted> you are probably asleep 2016-07-01 02:58:45 <name redacted> I hope fish was fishy in a good eay 2016-07-01 02:58:56 <name redacted> ð 2016-07-01 02:59:34 <name redacted> ððð 2016-07-01 03:02:48 <name > British security is a little more rigorous...`; let m; while ((m = regex.exec(str)) !== null) { // This is necessary to avoid infinite loops with zero-width matches if (m.index === regex.lastIndex) { regex.lastIndex++; } // The result can be accessed through the `m`-variable. m.forEach((match, groupIndex) => { console.log(`Found match, group ${groupIndex}: ${match}`); }); }
Si ce n'était pas l'expression souhaitée, vous pouvez modifier / changer vos expressions dans regex101.com . Vous pouvez ajouter plus de limites si nécessaire.
Vous pouvez également visualiser vos expressions dans jex.im :
(.*)(\s<name.*)
Javascript n'était pas le langage prévu pour les balises et le corps de la question. De plus, les conventions de regex dans R ne sont pas les mêmes que celles de javascript.
En utilisant l'expression régulière de base R utilisée dans la fonction gsub, il est possible d'extraire chaque information. Supposons que ce fichier soit un exemple:
your_data <- readLines(your_text_file) # Reading pattern <- "(.*) <(\\S*) (\\S*)>(.*)" # The regex pattern times <- gsub(pattern,"\\1",your_data) # Get Time and date person_name <- gsub(pattern,"\\2 \\3",your_data) # Get name message <- gsub(pattern,"\\4",your_data) # Get message
Maintenant, dans la console R, vous lisez le fichier comme un simple texte et traitez-le par une regex. L'argument 2 de gsub est d'extraire le modèle de regex
2016-07-01 02:50:35 <name1 surname1> hey 2016-07-01 02:51:26 <name1 surname1> waiting for plane to Edinburgh 2016-07-01 02:51:45 <name1 surname1> thinking about 2016-07-01 02:52:07 <name2 surname2> nothing crappy 2016-07-01 02:52:20 <name2 surname2> plane went by pretty fast 2016-07-01 02:54:08 <name2 surname2> no idea 2016-07-01 02:54:17 <name2 surname2> just know it's london 2016-07-01 02:56:44 <name1 surname1> you are probably asleep 2016-07-01 02:58:45 <name1 surname1> I hope fish was fishy in a good eay 2016-07-01 02:58:56 <name2 surname2> x 2016-07-01 02:59:34 <name1 surname2> y 2016-07-01 03:02:48 <name2 > British security is a little more rigorous...
J'ai essayé cela, mais je ne vois pas en quoi chacune des sorties est différente. Ils se ressemblent tous, et l'expression régulière ne semble pas non plus si différente dans votre exemple. N'était-ce pas destiné à être testé? ce que ce n'est qu'un exemple hypothétique? Comme si j'étais censé écrire ma propre regex? Mais je suis d'accord avec vous que cela devrait être possible. Ce serait bien d'écrire une regex qui ferait ce travail, c'est-à-dire d'extraire chaque aspect de ces données dans sa propre colonne.
cela ressemble à ceci quand j'ai exécuté ce code:> head (person) [1] "ï» ¿2016-01-27 09:14:40 *** Jane Doe a commencé un chat vidéo "[2]" 2016-01- 27 09:15:20
En fait, c'est l'un des aspects ennuyeux de ces données. La ligne 2 (bien que ce ne soit pas la seule comme celle-ci) est longue:> test [2] [1] "2016-01-27 09:15:20
> test [150] [1] "2016-07-01 08:17:47
En utilisant votre exemple de texte collé, nous pouvons faire ce qui suit. Notez que votre description du comportement du texte lors du copier-coller me suggère qu'il y a en fait des caractères de retour à la ligne \ n
dans le texte, mais sans exemple reproductible, c'est difficile à dire.
Divisez la longue chaîne en lignes en divisant sur la limite avant une date. Si des personnes saisissent régulièrement des dates dans les messages, vous pouvez étendre le modèle pour inclure l'heure et le nom. Si les gens saisissent cela dans des messages, cela va être compliqué, mais j'espère n'affectera que quelques messages. Ce problème serait résolu en ayant des délimitations de ligne.
Placez les lignes dans une colonne de dataframe et divisez-les sur des espaces qui précèdent ou suivent un signe d'insertion ou
>
pour les diviser en nom et message. p>
library(tidyverse) text <- "2016-07-01 23:59:27 <John Doe> We're both signing off at the same time2016-07-02 00:00:04 <John Doe> :-)2016-07-02 00:00:28 <John Doe> I live you supercalagraa...phragrlous...esp..dociois2016-07-02 00:12:23 <Jane Doe> I love you :)2016-07-02 08:57:33" text %>% str_split("(?=\\d{4}-\\d{2}-\\d{2})") %>% pluck(1) %>% enframe(name = NULL, value = "message") %>% separate(message, c("datetime", "name", "message"), sep = "\\s(?=<)|(?<=>)\\s", extra = "merge") #> Warning: Expected 3 pieces. Missing pieces filled with `NA` in 2 rows [1, #> 6]. #> # A tibble: 6 x 3 #> datetime name message #> <chr> <chr> <chr> #> 1 "" <NA> <NA> #> 2 2016-07-01 23:59:⦠<John Do⦠We're both signing off at the same time #> 3 2016-07-02 00:00:⦠<John Do⦠:-) #> 4 2016-07-02 00:00:⦠<John Do⦠I live you supercalagraa...phragrlous...esp⦠#> 5 2016-07-02 00:12:⦠<Jane Do⦠I love you :) #> 6 2016-07-02 08:57:⦠<NA> <NA>
Créé le 16/05/2019 par le reprex paquet (v0.2.1)
J'ai pu reproduire ce que vous venez de faire (parce que je l'ai juste coupé et collé dans R), mais, quand je l'ai essayé avec le fichier entier, qui est gros, il n'a renvoyé que deux lignes brisées, mais cela pourrait être parce que le premier et les deuxièmes lignes du fichier entier sont étranges: 27/01/2016 09:14:40 *** Jane Doe a commencé un chat vidéo 27/01/2016 09:15:20
> test [85] [1] "2016-07-01 02:50:35
Avec un peu d'aide, j'ai pu comprendre.
> a <- readLines ("hangouts-conversation-6.txt", encoding = "UTF-8") > b <- "^([0-9-]{10} [0-9:]{8} )[*]{3} (\\w+ \\w+)" > c <- gsub(b, "\\1<\\2> ", a) > d <- "^([0-9-]{10}) ([0-9:]{8}) <(\\w+ \\w+)>\\s*(.+)$" > e <- data.frame(date = character(), + time = character(), + name = character(), + text = character(), + stringsAsFactors = TRUE) f <- strcapture(d, c, e) > f <- f [-c(1),]
La première ligne était tous les NA, d'où la dernière fois avec le -c
Et, encore une fois, cela devrait fonctionner avec d'autres fichiers de données Google Hangouts. d'où vient le code.
Les noms ont-ils une longueur cohérente? sont-ils enveloppés dans des tapis comme indiqué? y a-t-il un délimiteur?
Il y a des incohérences. Par exemple, la plupart du temps, il n'y a pas d'espace entre la fin d'une ligne et la suivante, mais parfois, rarement, il y en a. 2016-01-27 09:15:20 Salut 2016-01-27 09:15:22. Alors là, il y a un espace entre le Hey et le 2016, mais c'est parce que l'espace fait partie du message lui-même. S'il n'y a pas d'espace dans le message lui-même, ils sont collés ensemble comme ceci: 2016-07-01 02:50:35 hey2016-07-01 02:51:26 en attendant l'avion pour Edimbourg2016 -07-01 02:51:45 Remarquez alors que le hey est juste à côté du 2016. Pas d'espace.
Mais il y a toujours un espace entre les noms avec les carottes. Voici les données de Google Hangouts. La structure est la suivante. Il y a toujours une date, qui est séparée par un seul espace avant l'heure, qui est séparée par un seul espace du nom , qui est séparé par un seul espace du message lui-même, bien que, encore une fois, le message lui-même pourrait ou non se terminer sur un espace.
Fait intéressant, dès que je le colle dans un e-mail ou même dans ces boîtes de débordement de pile, la structure est immédiatement reconnue et les zones de texte formate correctement le texte. Mais, dans le fichier texte lui-même, cela ressemble à ceci.
2016-07-01 23:59:27 Nous nous déconnectons tous les deux en même temps2016-07-02 00:00:04 :-) 2016-07-02 00:00:28 Je vous vis supercalagraa ... phragrlous ... esp..dociois2016-07-02 00:12:23 Je t'aime :) 2016-07-02 08:57:33
Ayant travaillé un peu plus avec les données, je reconnais maintenant que, idéalement, je veux les données dans un data.frame, avec des colonnes comme, date, heure, personne et commentaire. Mais cela pourrait même ne pas être possible à cause du problème d'espace, du fait qu'il y a des incohérences dans les données, du fait qu'il y a parfois un espace avant le début de la date (2016-07-01 23:59:27), et parfois il n'y en a pas. Il semble que cela rendrait une expression régulière impossible.