1
votes

Une regex pour diviser une chaîne de texte en R

J'ai une très longue chaîne comme cet exemple ci-dessous et j'ai du mal à trouver une expression régulière pour la diviser en parties selon le motif, par exemple: '1. OEA / AC »et« 2. OEA / AD '.

Cette tranche de texte a:

1) un nombre variable au début

2) deux lettres majuscules variant de A à Z

J'ai essayé ceci:

require(stringr)
have <- "1. OAS / AC 12345/this is a test string to regex, 2. OAS / AD     79856/this is another test string to regex, 3. OAS / AE 87987/this is a new test string to regex. 4. OAS / AZ 78798456/this is one mode test string to regex."
want <- stringr::str_split(have, "([1-9])( OAS / )([A-Z]{2})")

want <- list(
         "1. OAS / AC " = "12345/this is a test string to regex,",
         "2. OAS / AD " = "79856/this is another test string to regex,",
         "3. OAS / AE " = "87987/this is a new test string to regex.",
         "4. OAS / AZ " = "78798456/this is one mode test string to regex."
)

mais ça ne marche pas

Merci d'avance, pour toute aide!

Exemple p>

x <- stringr::str_split(have, "([1-9])( OAS / )([A-Z]{2})")


3 commentaires

Essayez stringr :: str_match_all (have, "(\\ d + \\. OAS / [AZ] {2}) \\ s * (. *?) (? = \\ s * \\ d + \\. OEA / [AZ] {2} | \\ z) ")


Salut @ WiktorStribiżew. J'étais loin d'avoir une telle solution. Merci beaucoup pour l'aide.


Heureux que cela ait fonctionné pour vous. Veuillez envisager d'accepter la réponse en cliquant sur ✓ à gauche (voir Comment accepter les réponses SO ) et voter si ma réponse vous a été utile (voir Comment faire vote positif sur Stack Overflow? ).


3 Réponses :


1
votes

Nous pourrions le faire avec une anticipation positive, en recherchant le modèle d'un nombre, suivi d'un peroid:

str_split(have, "(?=\\d{1,2}\\.)") %>% unlist() %>% .[-1]

[1] "1. OAS / AC 12345/this is a test string to regex, "           "2. OAS / AD     79856/this is another test string to regex, "
[3] "3. OAS / AE 87987/this is a new test string to regex. "       "4. OAS / AZ 78798456/this is one mode test string to regex." 

Et nous pouvons le nettoyer davantage:

str_split(have, "(?=\\d+\\.)")

[1] ""                                                             "1. OAS / AC 12345/this is a test string to regex, "          
[3] "2. OAS / AD     79856/this is another test string to regex, " "3. OAS / AE 87987/this is a new test string to regex. "      
[5] "4. OAS / AZ 78798456/this is one mode test string to regex."


1 commentaires

Salut @ Mako212. Je vous remercie beaucoup pour votre aide. Cela aidera beaucoup.



0
votes

Vous pouvez utiliser

dput(res)
# => structure(c("12345/this is a test string to regex,", "79856/this is another test string to regex,", 
#  "87987/this is a new test string to regex.", "78798456/this is one mode test string to regex."
#  ), .Names = c("1. OAS / AC", "2. OAS / AD", "3. OAS / AE", "4. OAS / AZ"
#  ))

Résultat:

library(stringr)
have <- "1. OAS / AC 12345/this is a test string to regex, 2. OAS / AD     79856/this is another test string to regex, 3. OAS / AE 87987/this is a new test string to regex. 4. OAS / AZ 78798456/this is one mode test string to regex."
r <- stringr::str_match_all(have, "(\\d+\\. OAS / [A-Z]{2})\\s*(.*?)(?=\\s*\\d+\\. OAS / [A-Z]{2}|\\z)")
res <- r[[1]][,3]
names(res) <- r[[1]][,2]

Voir le Démo regex .

Détails du modèle

  • (\ d + \. OAS / [A-Z] {2}) - Groupe de capture 1:
    • \ d + - 1+ chiffres
    • \. - un .
    • OAS / - une sous-chaîne littérale OAS /
    • [A-Z] {2} - deux lettres majuscules
  • \ s * - 0+ espaces blancs
  • (. *?) - Groupe de capture 2: 0+ caractères autres que les caractères de saut de ligne, aussi peu que possible
  • (? = \ s * \ d + \. OAS / [A-Z] {2} | \ z) - une anticipation positive: immédiatement à droite de l'emplacement actuel, il doit
    • \ s * \ d + \. OAS / [A-Z] {2} - 0+ espaces blancs, 1+ chiffres, . , espace, / , espace, deux lettres majuscules
    • | - ou
    • \ z - fin de chaîne.


0 commentaires

0
votes

La manière dont vous avez décrit le problème n'est pas claire, mais si vous voulez simplement extraire jusqu'à "OAS / AC" ,

gsub("([A-Z])\\s*([0-9])","\\1 = \\2",have,perl=T)

Pour la fonction ci-dessus fonctionne, les phrases doivent être des chaînes individuelles dans un vecteur de caractères

Si votre objectif est d'insérer un signe "=" entre la sous-chaîne de deux lettres et le nombre après "OAS",

library(qdap)
beg2char(have, " ", 4)#looks for the fourth occurrence of \\s and extracts everything before it.


0 commentaires