1
votes

Comment séparer la chaîne des nombres dans R?

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?


6 commentaires

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.


4 Réponses :


1
votes

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}`);
    });
}

 entrez la description de l'image ici a >

RegEx

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.

Circuit RegEx

Vous pouvez également visualiser vos expressions dans jex.im :

 entrez la description de l'image ici

Démo JavaScript

(.*)(\s<name.*)


1 commentaires

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.



0
votes

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...


4 commentaires

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 lh3.googleusercontent.com / -_ WQF5kRcnpk / Vqj7J4aK1jI / AAAAAAAAA‌ VA /… " [3] "2016-01-27 09:15:20 Hey"


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 Dîner"



0
votes

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.

  1. 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.

  2. 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)


3 commentaires

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 Les 84 premières lignes ont cette structure:> test2 [84] [1] "2016-06-28 21:12:43 *** John Doe a mis fin à un chat vidéo"


> test [85] [1] "2016-07-01 02:50:35 hey"



0
votes

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


1 commentaires

Et, encore une fois, cela devrait fonctionner avec d'autres fichiers de données Google Hangouts. d'où vient le code.