web-dev-qa-db-fra.com

conserver uniquement les caractères alphanumériques et l'espace dans une chaîne à l'aide de gsub

J'ai une chaîne contenant des caractères alphanumériques, des caractères spéciaux et des caractères non UTF-8. Je veux supprimer les caractères spéciaux et non utf-8.

Voici ce que j'ai essayé:

gsub('[^0-9a-z\\s]','',"�+ Sample string here =�{�>E�BH�P<]�{�>")

Cependant, ceci supprime les caractères spéciaux (signes de ponctuation + non utf8) mais la sortie n'a pas d'espaces.

gsub('/[^0-9a-z\\s]/i','',"�+ Sample string here =�{�>E�BH�P<]�{�>")

Le résultat a des espaces mais il y a toujours des caractères non utf8 présents.

Des travaux?

Pour l'exemple de chaîne ci-dessus, la sortie doit être: Exemple de chaîne ici

9
lilipunk

Vous pouvez utiliser les classes [:alnum:] et [:space:] pour ça:

sample_string <- "�+ Sample 2 string here =�{�>E�BH�P<]�{�>"
gsub("[^[:alnum:][:space:]]","",sample_string)
#> [1] "ï Sample 2 string here ïïEïBHïPïï"

Vous pouvez également utiliser des codes PCRE pour faire référence à des jeux de caractères spécifiques:

gsub("[^\\p{L}0-9\\s]","",sample_string, Perl = TRUE)
#> [1] "ï Sample 2 string here ïïEïBHïPïï"

Les deux cas illustrent clairement que les caractères toujours présents sont considérés comme des lettres. De plus, l'EBHP à l'intérieur sont toujours des lettres, donc la condition à laquelle vous remplacez n'est pas correcte. Vous ne voulez pas garder toutes les lettres, vous voulez juste garder A-Z, a-z et 0-9:

gsub("[^A-Za-z0-9 ]","",sample_string)
#> [1] " Sample 2 string here EBHP"

Il contient toujours l'EBHP. Si vous voulez vraiment garder une section qui ne contient que des lettres et des chiffres, vous devez utiliser la logique inverse: sélectionnez ce que vous voulez et remplacez tout sauf en utilisant des références arrières:

gsub(".*?([A-Za-z0-9 ]+)\\s.*","\\1", sample_string)
#> [1] " Sample 2 string here "

Ou, si vous souhaitez rechercher une chaîne, même non liée par des espaces, utilisez la limite de mot \\b au lieu:

gsub(".*?(\\b[A-Za-z0-9 ]+\\b).*","\\1", sample_string)
#> [1] "Sample 2 string here"

Que se passe t-il ici:

  • .*? correspond à n'importe quoi (.) au moins 0 fois (*) mais non homogène (?). Cela signifie que gsub essaiera d'adapter la plus petite quantité possible à cette pièce.
  • tout entre () sera stocké et pourra être référencé dans le remplacement par \\1
  • \\b indique une limite de Word
  • Ceci est suivi au moins une fois (+) par tout caractère A-Z, a-z, 0-9 ou un espace. Vous devez le faire de cette façon, car les lettres spéciales sont contenues entre les majuscules et les minuscules dans la table de code. Donc, en utilisant A-z inclura toutes les lettres spéciales (qui sont UTF-8 btw!)
  • après cette séquence, ajustez n'importe quoi au moins zéro fois pour supprimer le reste de la chaîne.
  • la référence arrière \\1 en combinaison avec .* dans l'expression régulière, s'assurera que seule la partie requise reste dans la sortie.
12
Joris Meys

stringr peut utiliser un moteur regex différent qui prend en charge les classes de caractères POSIX. Le: ascii: nomme la classe, qui doit généralement être placée entre crochets [: asciii:], dans le crochet extérieur. Le [^ indique la négation de la correspondance.

library(stringr)
str_replace_all("�+ Sample string here =�{�>E�BH�P<]�{�>", "[^[:ascii:]]", "")

[1] "+ exemple de chaîne ici = {> EBHP <] {>"

0
Andrew Lavers