Comment puis-je supprimer tous les signes de ponctuation d'une chaîne en JavaScript à l'aide de regex?

152

Si j'ai une chaîne avec n'importe quel type de caractère non alphanumérique:

"This., -/ is #! an $ % ^ & * example ;: {} of a = -_ string with `~)() punctuation"

Comment en obtenir une version sans ponctuation en JavaScript:

"This is an example of a string with punctuation"
Quentin Fisk
la source

Réponses:

211

Si vous souhaitez supprimer une ponctuation spécifique d'une chaîne, il sera probablement préférable de supprimer explicitement exactement ce que vous voulez

replace(/[.,\/#!$%\^&\*;:{}=\-_`~()]/g,"")

Faire ce qui précède ne renvoie toujours pas la chaîne telle que vous l'avez spécifiée. Si vous souhaitez supprimer les espaces supplémentaires restants suite à la suppression de la ponctuation folle, vous allez vouloir faire quelque chose comme

replace(/\s{2,}/g," ");

Mon exemple complet:

var s = "This., -/ is #! an $ % ^ & * example ;: {} of a = -_ string with `~)() punctuation";
var punctuationless = s.replace(/[.,\/#!$%\^&\*;:{}=\-_`~()]/g,"");
var finalString = punctuationless.replace(/\s{2,}/g," ");

Résultats de l'exécution du code dans la console Firebug:

texte alternatif

Mike Grace
la source
4
Les accolades en regex appliquent un quantificateur au précédent, donc dans ce cas, il remplace entre 2 et 100 caractères \sd'espacement ( ) par un seul espace. Si vous souhaitez réduire un certain nombre de caractères blancs à un seul, vous quitteriez de la limite supérieure comme ceci: replace(/\s{2,}/g, ' ').
Mike Partridge
13
J'ai ajouté quelques caractères de plus à la liste des signes de ponctuation remplacé ( @+?><[]+): replace(/[\.,-\/#!$%\^&\*;:{}=\-_`~()@\+\?><\[\]\+]/g, ''). Si quelqu'un cherche un ensemble encore légèrement plus complet.
timmfin
9
Python's string.punctuation définit la ponctuation comme: !"#$%&'()*+,-./:;<=>?@[\]^_`{|}~Ce qui fonctionne mieux pour moi, donc une autre alternative serait:replace(/['!"#$%&\\'()\*+,\-\.\/:;<=>?@\[\\\]\^_`{|}~']/g,"");
01AutoMonkey
1
@ AntoineLizée Je reconnais que c'est trompeur. Mise à jour de la réponse. Merci.
Mike Grace
2
J'ai essayé avec "ça?" - ne fonctionne pas pour moi ( regex101.com/r/F4j5Qc/1 ), la bonne solution est: /[.,\/#!$%\^&*;:{}=\-_ `~ () \?] / g
Maxim Firsoff
129
str = str.replace(/[^\w\s]|_/g, "")
         .replace(/\s+/g, " ");

Supprime tout sauf les caractères alphanumériques et les espaces, puis réduit plusieurs caractères adjacents en espaces simples.

Explication détaillée:

  1. \w est un chiffre, une lettre ou un trait de soulignement.
  2. \s est n'importe quel espace blanc.
  3. [^\w\s] est tout ce qui n'est pas un chiffre, une lettre, un espace ou un trait de soulignement.
  4. [^\w\s]|_ est le même que le n ° 3 sauf avec les traits de soulignement ajoutés.
John Kugelman
la source
72
Cela supprimera également les caractères non anglais mais parfaitement alphanumériques comme à, é, ö, ainsi que l'ensemble de l'alphabet cyrillique.
Dan Abramov
5
@quemeful Je ne suis pas d'accord, la question d'origine ne précise pas "pour l'anglais uniquement". SO est assez international, utilisé partout dans le monde. Quiconque parle anglais et a accès à Internet peut l'utiliser. Si la langue n'est pas spécifiée dans la question, nous ne devrions faire aucune hypothèse. Nous sommes en 2017, bon sang!
Rolf
1
De plus, même si vous ne supportez que l'anglais, vous avez des mots d'emprunt comme un CV et des noms de lieux ou de personnes, vous ne voudriez donc pas empêcher quelqu'un de dire qu'il travaille à San José (l'orthographe officielle) dans le box entre Ramón Chloé.
Chris Adams
Cela va jouer avec des mots tels que wouldn'tetdon't
Charlie
71

Voici les caractères de ponctuation standard pour US-ASCII: !"#$%&'()*+,-./:;<=>?@[\]^_`{|}~

Pour la ponctuation Unicode (comme les guillemets, les tirets em, etc.), vous pouvez facilement faire correspondre des plages de blocs spécifiques. Le bloc de ponctuation générale est \u2000-\u206F, et le bloc de ponctuation supplémentaire est \u2E00-\u2E7F.

Mis ensemble et correctement échappé, vous obtenez le RegExp suivant:

/[\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*+,\-.\/:;<=>?@\[\]^_`{|}~]/

Cela devrait correspondre à peu près à toutes les ponctuations que vous rencontrez. Donc, pour répondre à la question initiale:

var punctRE = /[\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*+,\-.\/:;<=>?@\[\]^_`{|}~]/g;
var spaceRE = /\s+/g;
var str = "This, -/ is #! an $ % ^ & * example ;: {} of a = -_ string with `~)() punctuation";
str.replace(punctRE, '').replace(spaceRE, ' ');

>> "This is an example of a string with punctuation"

Source US-ASCII: http://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html#posix

Source Unicode: http://kourge.net/projects/regexp-unicode-block

Joseph
la source
3
Pour la ponctuation Unicode, les blocs ne suffisent pas. Vous devez regarder la catégorie générale Ponctuation, et vous verrez que toutes les ponctuations ne sont pas bien situées dans ces blocs. Il existe de nombreuses ponctuations familières dans les blocs latins, par exemple.
nhahtdh
15

/ [^ A-Za-z0-9 \ s] / g doit correspondre à toutes les ponctuations mais conserver les espaces. Vous pouvez donc utiliser .replace(/\s{2,}/g, " ")pour remplacer des espaces supplémentaires si vous avez besoin de le faire. Vous pouvez tester l'expression régulière sur http://rubular.com/

.replace(/[^A-Za-z0-9\s]/g,"").replace(/\s{2,}/g, " ")

Mise à jour : ne fonctionnera que si l'entrée est en anglais ANSI.

adnan2nd
la source
6
Vous supposez que la chaîne est en anglais ANSI. Pas le français avec des lettres accentuées (àéô), ni l'allemand, le turc. Unicode arabe, chinois, etc. disparaîtra également.
Rolf
2
Merci, je n'y ai pas pensé complètement.
adnan2nd
10

J'ai rencontré le même problème, cette solution a fait l'affaire et était très lisible:

var sentence = "This., -/ is #! an $ % ^ & * example ;: {} of a = -_ string with `~)() punctuation";
var newSen = sentence.match(/[^_\W]+/g).join(' ');
console.log(newSen);

Résultat:

"This is an example of a string with punctuation"

L'astuce consistait à créer un ensemble annulé . Cela signifie qu'il correspond à tout ce qui n'est pas dans l'ensemble, c'est [^abc]-à- dire - pas a, b ou c

\West n'importe quel non-mot, donc [^\W]+annulera tout ce qui n'est pas un mot char .

En ajoutant le _ (trait de soulignement), vous pouvez également annuler cela.

Faites-le s'appliquer globalement /g, vous pouvez alors exécuter n'importe quelle chaîne et effacer la ponctuation:

/[^_\W]+/g

Agréable et propre ;)

Jacobedawson
la source
1
Vous modifiez également toutes les nouvelles lignes dans l'espace avec cette méthode.
nhahtdh
5
Cette méthode ne fonctionne qu'en anglais, tous les caractères accentués sont supprimés.
NicolasBernier
@NicolasBernier ouais c'est 100% correct - le moteur de regex de JavaScript est en fait assez boiteux (voir: stackoverflow.com/questions/4043307/… ) - malheureusement pour les tâches plus complexes (et pour créer des modèles pour des mots non anglais) cela prend un peu plus de code. Pourtant, pour une
expression régulière
C'était le plus simple et cela a bien servi mon objectif.
James Shrum
9

Je vais juste le mettre ici pour les autres.

Faites correspondre tous les caractères de ponctuation pour toutes les langues:

Construit à partir de la catégorie de ponctuation Unicode et ajouté des symboles de clavier courants tels $que des crochets et\-=_

http://www.fileformat.info/info/unicode/category/Po/list.htm

remplacement de base:

".test'da, te\"xt".replace(/[\-=_!"#%&'*{},.\/:;?\(\)\[\]@\\$\^*+<>~`\u00a1\u00a7\u00b6\u00b7\u00bf\u037e\u0387\u055a-\u055f\u0589\u05c0\u05c3\u05c6\u05f3\u05f4\u0609\u060a\u060c\u060d\u061b\u061e\u061f\u066a-\u066d\u06d4\u0700-\u070d\u07f7-\u07f9\u0830-\u083e\u085e\u0964\u0965\u0970\u0af0\u0df4\u0e4f\u0e5a\u0e5b\u0f04-\u0f12\u0f14\u0f85\u0fd0-\u0fd4\u0fd9\u0fda\u104a-\u104f\u10fb\u1360-\u1368\u166d\u166e\u16eb-\u16ed\u1735\u1736\u17d4-\u17d6\u17d8-\u17da\u1800-\u1805\u1807-\u180a\u1944\u1945\u1a1e\u1a1f\u1aa0-\u1aa6\u1aa8-\u1aad\u1b5a-\u1b60\u1bfc-\u1bff\u1c3b-\u1c3f\u1c7e\u1c7f\u1cc0-\u1cc7\u1cd3\u2016\u2017\u2020-\u2027\u2030-\u2038\u203b-\u203e\u2041-\u2043\u2047-\u2051\u2053\u2055-\u205e\u2cf9-\u2cfc\u2cfe\u2cff\u2d70\u2e00\u2e01\u2e06-\u2e08\u2e0b\u2e0e-\u2e16\u2e18\u2e19\u2e1b\u2e1e\u2e1f\u2e2a-\u2e2e\u2e30-\u2e39\u3001-\u3003\u303d\u30fb\ua4fe\ua4ff\ua60d-\ua60f\ua673\ua67e\ua6f2-\ua6f7\ua874-\ua877\ua8ce\ua8cf\ua8f8-\ua8fa\ua92e\ua92f\ua95f\ua9c1-\ua9cd\ua9de\ua9df\uaa5c-\uaa5f\uaade\uaadf\uaaf0\uaaf1\uabeb\ufe10-\ufe16\ufe19\ufe30\ufe45\ufe46\ufe49-\ufe4c\ufe50-\ufe52\ufe54-\ufe57\ufe5f-\ufe61\ufe68\ufe6a\ufe6b\uff01-\uff03\uff05-\uff07\uff0a\uff0c\uff0e\uff0f\uff1a\uff1b\uff1f\uff20\uff3c\uff61\uff64\uff65]+/g,"")
"testda text"

ajouté \ s comme espace

".da'fla, te\"te".split(/[\s\-=_!"#%&'*{},.\/:;?\(\)\[\]@\\$\^*+<>~`\u00a1\u00a7\u00b6\u00b7\u00bf\u037e\u0387\u055a-\u055f\u0589\u05c0\u05c3\u05c6\u05f3\u05f4\u0609\u060a\u060c\u060d\u061b\u061e\u061f\u066a-\u066d\u06d4\u0700-\u070d\u07f7-\u07f9\u0830-\u083e\u085e\u0964\u0965\u0970\u0af0\u0df4\u0e4f\u0e5a\u0e5b\u0f04-\u0f12\u0f14\u0f85\u0fd0-\u0fd4\u0fd9\u0fda\u104a-\u104f\u10fb\u1360-\u1368\u166d\u166e\u16eb-\u16ed\u1735\u1736\u17d4-\u17d6\u17d8-\u17da\u1800-\u1805\u1807-\u180a\u1944\u1945\u1a1e\u1a1f\u1aa0-\u1aa6\u1aa8-\u1aad\u1b5a-\u1b60\u1bfc-\u1bff\u1c3b-\u1c3f\u1c7e\u1c7f\u1cc0-\u1cc7\u1cd3\u2016\u2017\u2020-\u2027\u2030-\u2038\u203b-\u203e\u2041-\u2043\u2047-\u2051\u2053\u2055-\u205e\u2cf9-\u2cfc\u2cfe\u2cff\u2d70\u2e00\u2e01\u2e06-\u2e08\u2e0b\u2e0e-\u2e16\u2e18\u2e19\u2e1b\u2e1e\u2e1f\u2e2a-\u2e2e\u2e30-\u2e39\u3001-\u3003\u303d\u30fb\ua4fe\ua4ff\ua60d-\ua60f\ua673\ua67e\ua6f2-\ua6f7\ua874-\ua877\ua8ce\ua8cf\ua8f8-\ua8fa\ua92e\ua92f\ua95f\ua9c1-\ua9cd\ua9de\ua9df\uaa5c-\uaa5f\uaade\uaadf\uaaf0\uaaf1\uabeb\ufe10-\ufe16\ufe19\ufe30\ufe45\ufe46\ufe49-\ufe4c\ufe50-\ufe52\ufe54-\ufe57\ufe5f-\ufe61\ufe68\ufe6a\ufe6b\uff01-\uff03\uff05-\uff07\uff0a\uff0c\uff0e\uff0f\uff1a\uff1b\uff1f\uff20\uff3c\uff61\uff64\uff65]+/g)

ajouté ^ pour inverser patternt pour correspondre non pas à la ponctuation mais aux mots eux-mêmes

".test';the, te\"xt".match(/[^\s\-=_!"#%&'*{},.\/:;?\(\)\[\]@\\$\^*+<>~`\u00a1\u00a7\u00b6\u00b7\u00bf\u037e\u0387\u055a-\u055f\u0589\u05c0\u05c3\u05c6\u05f3\u05f4\u0609\u060a\u060c\u060d\u061b\u061e\u061f\u066a-\u066d\u06d4\u0700-\u070d\u07f7-\u07f9\u0830-\u083e\u085e\u0964\u0965\u0970\u0af0\u0df4\u0e4f\u0e5a\u0e5b\u0f04-\u0f12\u0f14\u0f85\u0fd0-\u0fd4\u0fd9\u0fda\u104a-\u104f\u10fb\u1360-\u1368\u166d\u166e\u16eb-\u16ed\u1735\u1736\u17d4-\u17d6\u17d8-\u17da\u1800-\u1805\u1807-\u180a\u1944\u1945\u1a1e\u1a1f\u1aa0-\u1aa6\u1aa8-\u1aad\u1b5a-\u1b60\u1bfc-\u1bff\u1c3b-\u1c3f\u1c7e\u1c7f\u1cc0-\u1cc7\u1cd3\u2016\u2017\u2020-\u2027\u2030-\u2038\u203b-\u203e\u2041-\u2043\u2047-\u2051\u2053\u2055-\u205e\u2cf9-\u2cfc\u2cfe\u2cff\u2d70\u2e00\u2e01\u2e06-\u2e08\u2e0b\u2e0e-\u2e16\u2e18\u2e19\u2e1b\u2e1e\u2e1f\u2e2a-\u2e2e\u2e30-\u2e39\u3001-\u3003\u303d\u30fb\ua4fe\ua4ff\ua60d-\ua60f\ua673\ua67e\ua6f2-\ua6f7\ua874-\ua877\ua8ce\ua8cf\ua8f8-\ua8fa\ua92e\ua92f\ua95f\ua9c1-\ua9cd\ua9de\ua9df\uaa5c-\uaa5f\uaade\uaadf\uaaf0\uaaf1\uabeb\ufe10-\ufe16\ufe19\ufe30\ufe45\ufe46\ufe49-\ufe4c\ufe50-\ufe52\ufe54-\ufe57\ufe5f-\ufe61\ufe68\ufe6a\ufe6b\uff01-\uff03\uff05-\uff07\uff0a\uff0c\uff0e\uff0f\uff1a\uff1b\uff1f\uff20\uff3c\uff61\uff64\uff65]+/g)

pour une langue comme l'hébreu, peut-être supprimer "" les guillemets simples et doubles. Et y réfléchir davantage.

en utilisant ce script:

étape 1: sélectionnez dans Firefox en tenant le contrôle une colonne de numéros U + 1234 et copiez-la, ne copiez pas U + 12456 ils remplacent l'anglais

étape 2 (je l'ai fait dans chrome) trouvez une zone de texte et collez-la dedans, puis cliquez avec le bouton droit et cliquez sur inspecter. alors vous pouvez accéder à l'élément sélectionné avec $ 0.

var x=$0.value
var z=x.replace(/U\+/g,"").split(/[\r\n]+/).map(function(a){return parseInt(a,16)})
var ret=[];z.forEach(function(a,k){if(z[k-1]===a-1 && z[k+1]===a+1) { if(ret[ret.length-1]!="-")ret.push("-");} else {  var c=a.toString(16); var prefix=c.length<3?"\\u0000":c.length<5?"\\u0000":"\\u000000"; var uu=prefix.substring(0,prefix.length-c.length)+c; ret.push(c.length<3?String.fromCharCode(a):uu)}});ret.join("")

étape 3 copié sur les premières lettres l'ascii sous forme de caractères séparés et non de plages car quelqu'un pourrait ajouter ou supprimer des caractères individuels

Shimon Doodkin
la source
7

Dans un langage compatible Unicode, la propriété de caractère de ponctuation Unicode est \p{P}- que vous pouvez généralement abréger \pPet parfois développer pour plus \p{Punctuation}de lisibilité.

Utilisez-vous une bibliothèque d'expressions régulières compatible Perl?

tchrist
la source
8
Malheureusement, JS n'est pas compatible avec Perl. L'autre problème est que lorsque j'ai testé cela, il n'a pas capturé toute la ponctuation dans la chaîne de test de @ Quentin => mikegrace.s3.amazonaws.com/forums/stack-overflow
Mike Grace
4
Vous pouvez utiliser la bibliothèque XRegExp pour obtenir cette syntaxe étendue.
Eirik Birkeland le
7

Si vous souhaitez supprimer la ponctuation d'une chaîne, vous devez utiliser la Pclasse Unicode.

Mais, comme les classes ne sont pas acceptées dans le JavaScript RegEx, vous pouvez essayer ce RegEx qui devrait correspondre à toutes les ponctuations. Il correspond aux catégories suivantes: Pc Pd Pe Pf Pi Po Ps Sc Sk Sm So GeneralPunctuation SupplementalPunctuation CJKSymbolsAndPunctuation CuneiformNumbersAndPunctuation.

Je l'ai créé à l'aide de cet outil en ligne qui génère des expressions régulières spécifiquement pour JavaScript. C'est le code pour atteindre votre objectif:

var punctuationRegEx = /[!-/:-@[-`{-~¡-©«-¬®-±´¶-¸»¿×÷˂-˅˒-˟˥-˫˭˯-˿͵;΄-΅·϶҂՚-՟։-֊־׀׃׆׳-״؆-؏؛؞-؟٪-٭۔۩۽-۾܀-܍߶-߹।-॥॰৲-৳৺૱୰௳-௺౿ೱ-ೲ൹෴฿๏๚-๛༁-༗༚-༟༴༶༸༺-༽྅྾-࿅࿇-࿌࿎-࿔၊-၏႞-႟჻፠-፨᎐-᎙᙭-᙮᚛-᚜᛫-᛭᜵-᜶។-៖៘-៛᠀-᠊᥀᥄-᥅᧞-᧿᨞-᨟᭚-᭪᭴-᭼᰻-᰿᱾-᱿᾽᾿-῁῍-῏῝-῟῭-`´-῾\u2000-\u206e⁺-⁾₊-₎₠-₵℀-℁℃-℆℈-℉℔№-℘℞-℣℥℧℩℮℺-℻⅀-⅄⅊-⅍⅏←-⏧␀-␦⑀-⑊⒜-ⓩ─-⚝⚠-⚼⛀-⛃✁-✄✆-✉✌-✧✩-❋❍❏-❒❖❘-❞❡-❵➔➘-➯➱-➾⟀-⟊⟌⟐-⭌⭐-⭔⳥-⳪⳹-⳼⳾-⳿⸀-\u2e7e⺀-⺙⺛-⻳⼀-⿕⿰-⿻\u3000-〿゛-゜゠・㆐-㆑㆖-㆟㇀-㇣㈀-㈞㈪-㉃㉐㉠-㉿㊊-㊰㋀-㋾㌀-㏿䷀-䷿꒐-꓆꘍-꘏꙳꙾꜀-꜖꜠-꜡꞉-꞊꠨-꠫꡴-꡷꣎-꣏꤮-꤯꥟꩜-꩟﬩﴾-﴿﷼-﷽︐-︙︰-﹒﹔-﹦﹨-﹫!-/:-@[-`{-・¢-₩│-○-�]|\ud800[\udd00-\udd02\udd37-\udd3f\udd79-\udd89\udd90-\udd9b\uddd0-\uddfc\udf9f\udfd0]|\ud802[\udd1f\udd3f\ude50-\ude58]|\ud809[\udc00-\udc7e]|\ud834[\udc00-\udcf5\udd00-\udd26\udd29-\udd64\udd6a-\udd6c\udd83-\udd84\udd8c-\udda9\uddae-\udddd\ude00-\ude41\ude45\udf00-\udf56]|\ud835[\udec1\udedb\udefb\udf15\udf35\udf4f\udf6f\udf89\udfa9\udfc3]|\ud83c[\udc00-\udc2b\udc30-\udc93]/g;
var string = "This., -/ is #! an $ % ^ & * example ;: {} of a = -_ string with `~)() punctuation";
var newString = string.replace(punctuationRegEx, '').replace(/(\s){2,}/g, '$1');
console.log(newString)

Salvatore
la source
5

Pour les chaînes en-US (anglais américain), cela devrait suffire:

"This., -/ is #! an $ % ^ & * example ;: {} of a = -_ string with `~)() punctuation".replace( /[^a-zA-Z ]/g, '').replace( /\s\s+/g, ' ' )

Sachez que si vous supportez UTF-8 et des caractères comme chinois / russe et tout, cela les remplacera également, vous devez donc vraiment spécifier ce que vous voulez.

meder omuraliev
la source
3

si vous utilisez lodash

_.words('This, is : my - test,line:').join(' ')

Cet exemple

_.words('"This., -/ is #! an $ % ^ & * example ;: {} of a = -_ string with `~)() punctuation"').join(' ')
Pankaj Avhad
la source
2

Selon la liste des ponctuations de Wikipedia, j'ai dû créer l'expression régulière suivante qui détecte les ponctuations:

[\.’'\[\](){}⟨⟩:,،、‒–—―…!.‹›«»‐\-?‘’“”'";/⁄·\&*@\•^†‡°”¡¿※#№÷׺ª%‰+−=‱¶′″‴§~_|‖¦©℗®℠™¤₳฿₵¢₡₢$₫₯֏₠€ƒ₣₲₴₭₺₾ℳ₥₦₧₱₰£៛₽₹₨₪৳₸₮₩¥]

Tushar Goswami
la source
2
Si vous utilisez cette expression régulière, vous devez également échapper votre délimiteur d'expression régulière. Par exemple, si vous utilisez /( le plus courant), il doit être échappé à l' intérieur de la classe de caractères ci - dessus en ajoutant une barre oblique inverse avant, comme ceci: \/. Voici comment vous l' utiliser: "String!! With, Punctuation.".replace(/[\.’'\[\](){}⟨⟩:,،、‒–—―…!.‹›«»‐\-?‘’“”'";\/⁄·\&*@\•^†‡°”¡¿※#№÷׺ª%‰+−=‱¶′″‴§~_|‖¦©℗®℠™¤₳฿₵¢₡₢$₫₯֏₠€ƒ₣₲₴₭₺₾ℳ₥₦₧₱₰£៛₽₹₨₪৳₸₮₩¥]+/g,""). Au fait, je ne vois le backtick (`) nulle part là-dedans, comment ça se fait?
Rolf
est manquant. Il semble difficile de trouver une liste de toutes les ponctuations.
Alex
1

Si vous souhaitez ne conserver que les alphabets et les espaces, vous pouvez faire:

str.replace(/[^a-zA-Z ]+/g, '').replace('/ {2,}/',' ')
codaddict
la source
8
Cela ne va-t-il pas faire plus que de la ponctuation? Unicode et autres?
Alex
3
Vous voulez dire "seulement les alphabets anglais et les espaces"
Rolf
0

Cela dépend de ce que vous essayez de retourner. J'ai utilisé ceci récemment:

return text.match(/[a-z]/i);
Amanda Koster
la source