¿Cómo puedo quitar toda la puntuación de una cadena en JavaScript usando regex?

152

Si tengo una cadena con cualquier tipo de carácter no alfanumérico:

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

¿Cómo obtendría una versión sin puntuación en JavaScript?

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

Respuestas:

210

Si desea eliminar la puntuación específica de una cadena, probablemente sea mejor eliminar explícitamente exactamente lo que desea

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

Hacer lo anterior aún no devuelve la cadena como la ha especificado. Si desea eliminar cualquier espacio adicional que haya quedado de eliminar la puntuación loca, entonces querrá hacer algo como

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

Mi ejemplo completo:

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

Resultados de ejecutar código en la consola firebug:

texto alternativo

Mike Grace
fuente
44
Las llaves en expresiones regulares aplican un cuantificador al anterior, por lo que en este caso reemplaza entre 2 y 100 caracteres de espacio en blanco ( \s) con un solo espacio. Si desea contraer cualquier número de espacios en blanco a una sola, que dejaría fuera del límite superior de este modo: replace(/\s{2,}/g, ' ').
Mike Partridge
13
He añadido unas cuantas más caracteres a la lista de puntuacion reemplazado ( @+?><[]+): replace(/[\.,-\/#!$%\^&\*;:{}=\-_`~()@\+\?><\[\]\+]/g, ''). Si alguien está buscando un conjunto aún un poco más completo.
timmfin
9
La secuencia de caracteres de Python define la puntuación como: !"#$%&'()*+,-./:;<=>?@[\]^_`{|}~Lo que funciona mejor para mí, por lo que otra alternativa sería:replace(/['!"#$%&\\'()\*+,\-\.\/:;<=>?@\[\\\]\^_`{|}~']/g,"");
01AutoMonkey
1
@ AntoineLizée Estoy de acuerdo en que es engañoso. Se actualizó la respuesta. Gracias.
Mike Grace
2
Lo he intentado con "eso?" - no funciona para mí ( regex101.com/r/F4j5Qc/1 ), la solución correcta es: /[.,\/#!$%\^&*;:{}=\-_ `~ () \?] / g
Maxim Firsoff
129
str = str.replace(/[^\w\s]|_/g, "")
         .replace(/\s+/g, " ");

Elimina todo excepto los caracteres alfanuméricos y los espacios en blanco, luego contrae varios caracteres adyacentes en espacios individuales.

Explicación detallada:

  1. \w es cualquier dígito, letra o guión bajo.
  2. \s es cualquier espacio en blanco.
  3. [^\w\s] es cualquier cosa que no sea un dígito, letra, espacio en blanco o guión bajo.
  4. [^\w\s]|_ es lo mismo que el n. ° 3, excepto con los guiones bajos agregados nuevamente.
John Kugelman
fuente
72
Esto también eliminará los caracteres no alfanuméricos, pero por lo demás perfectamente alfanuméricos, como à, é, ö, así como todo el alfabeto cirílico.
Dan Abramov
55
@quemeful No estoy de acuerdo, la pregunta original no especifica "solo para inglés". SO es bastante internacional, se usa en todo el mundo. Cualquiera que hable inglés y tenga acceso a internet puede usarlo. Si el idioma no se especifica en la pregunta, entonces no deberíamos hacer ninguna suposición. Estamos en 2017, maldita sea!
Rolf
1
Además, incluso si solo admite inglés, tiene palabras prestadas como currículum vitae y nombres de lugares o personas, por lo que no querrá romper la capacidad de alguien de decir que trabajan en San José (la ortografía oficial) en el cubículo entre Ramón Chloé.
Chris Adams
Esto se enredará con palabras como wouldn'tydon't
Charlie
71

Estos son los caracteres de puntuación estándar para US-ASCII: !"#$%&'()*+,-./:;<=>?@[\]^_`{|}~

Para la puntuación Unicode (como comillas rizadas, guiones cortos, etc.), puede coincidir fácilmente en rangos de bloque específicos. El bloque de puntuación general es \u2000-\u206F, y el bloque de puntuación suplementaria es \u2E00-\u2E7F.

En conjunto, y escapó adecuadamente, obtienes el siguiente RegExp:

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

Eso debería coincidir con casi cualquier puntuación que encuentre. Entonces, para responder la pregunta original:

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"

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

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

Joseph
fuente
3
Para la puntuación Unicode, los bloques no son suficientes. Tienes que mirar la categoría general Puntuación y verás que no todas las puntuaciones están bien ubicadas en esos bloques. Hay muchas puntuaciones familiares dentro de los bloques latinos, por ejemplo.
nhahtdh
15

/ [^ A-Za-z0-9 \ s] / g debe coincidir con todos los signos de puntuación pero mantener los espacios. Por lo tanto, puede usar .replace(/\s{2,}/g, " ")para reemplazar espacios adicionales si necesita hacerlo. Puede probar la expresión regular en http://rubular.com/

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

Actualización : solo funcionará si la entrada es ANSI English.

adnan2nd
fuente
66
Está suponiendo que la cadena es inglés ANSI. No francés con letras acentuadas (àéô), ni alemán, turco. El árabe Unicode, el chino, etc. también desaparecerán.
Rolf
2
Gracias, no pensé en eso por completo.
adnan2nd
10

Me encontré con el mismo problema, esta solución funcionó y fue muy legible:

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

Resultado:

"This is an example of a string with punctuation"

El truco consistía en crear un conjunto negado . Esto significa que coincide con todo lo que no está dentro del conjunto, es decir [^abc], no a, b o c

\Wno es una palabra, por [^\W]+lo que negará todo lo que no sea una palabra char .

Al agregar el _ (guión bajo) puede negar eso también.

Haga que se aplique globalmente /g, luego puede ejecutar cualquier cadena a través de él y borrar la puntuación:

/[^_\W]+/g

Bonito y limpio ;)

jacobedawson
fuente
1
También cambia todas las líneas nuevas al espacio con este método.
nhahtdh
55
Este método solo funciona en inglés, se eliminan todos los caracteres acentuados.
NicolasBernier
@NicolasBernier, sí, eso es 100% correcto: el motor de expresiones regulares de JavaScript es bastante aburrido (ver: stackoverflow.com/questions/4043307/… ), desafortunadamente para tareas más complejas (y para crear patrones para palabras que no están en inglés) toma bastante tiempo Más código. Aún así, para una expresión regular rápida y concisa para eliminar la puntuación funciona :)
jacobedawson
Este fue el más simple y sirvió bien a mi propósito.
James Shrum
9

Lo pondré aquí para otros.

Haga coincidir todos los caracteres de puntuación para todos los idiomas:

Construido a partir de la categoría de puntuación Unicode y agregado algunos símbolos de teclado comunes como $corchetes y\-=_

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

reemplazo básico:

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

agregado como espacio

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

agregado ^ para invertir el patrón para que coincida no con la puntuación sino con las palabras mismas

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

para un lenguaje como el hebreo tal vez para eliminar "'la comilla simple y la doble. Y pensar más en ello.

usando este script:

Paso 1: seleccione en Firefox con el control una columna de números U + 1234 y cópielo, no copie U + 12456, reemplazan Inglés

paso 2 (lo hice en Chrome), busque algo de área de texto y péguelo en él, luego haga clic derecho y haga clic en inspeccionar. entonces puede acceder al elemento seleccionado con $ 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("")

el paso 3 copió sobre las primeras letras el ascii como caracteres separados no rangos porque alguien podría agregar o eliminar caracteres individuales

Shimon Doodkin
fuente
7

En un lenguaje compatible con Unicode, la propiedad de caracteres de puntuación Unicode es \p{P}, que generalmente puede abreviarse \pPy, a veces, expandirse \p{Punctuation}para facilitar la lectura.

¿Está utilizando una biblioteca de expresiones regulares compatibles con Perl?

tchrist
fuente
8
Lamentablemente, JS no es compatible con Perl. El otro problema es que cuando probé esto, no capturó toda la puntuación en la cadena de prueba de @ Quentin => mikegrace.s3.amazonaws.com/forums/stack-overflow/…
Mike Grace el
44
Puede usar la biblioteca XRegExp para obtener esta sintaxis extendida.
Eirik Birkeland
7

Si desea eliminar la puntuación de cualquier cadena, debe usar la Pclase Unicode.

Pero, dado que las clases no se aceptan en JavaScript RegEx, puede probar este RegEx que debe coincidir con todos los signos de puntuación. Coincide con las siguientes categorías: Pc Pd Pe Pf Pi Po Ps Sc Sk Sm So GeneralPunctuation SupplementalPunctuation CJKSymbolsAndPunctuation CuneiformNumbersAndPunctuation.

Lo creé usando esta herramienta en línea que genera expresiones regulares específicamente para JavaScript. Ese es el código para alcanzar tu objetivo:

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
fuente
5

Para cadenas en-US (inglés americano) esto debería ser suficiente:

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

Tenga en cuenta que si admite UTF-8 y caracteres como chino / ruso y todo esto, esto también los reemplazará, por lo que realmente debe especificar lo que desea.

meder omuraliev
fuente
3

si está usando lodash

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

Este ejemplo

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

Según la lista de puntuación de Wikipedia, tuve que construir la siguiente expresión regular que detecta las puntuaciones:

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

Tushar Goswami
fuente
2
Si usa esta expresión regular, también debe escapar de su delimitador de expresión regular. Por ejemplo, si se utiliza /(la más común), entonces debe ser escapó dentro de la clase de caracteres anterior añadiendo una barra invertida antes, como esto: \/. Esta es la forma en que lo utilizaría: "String!! With, Punctuation.".replace(/[\.’'\[\](){}⟨⟩:,،、‒–—―…!.‹›«»‐\-?‘’“”'";\/⁄·\&*@\•^†‡°”¡¿※#№÷׺ª%‰+−=‱¶′″‴§~_|‖¦©℗®℠™¤₳฿₵¢₡₢$₫₯֏₠€ƒ₣₲₴₭₺₾ℳ₥₦₧₱₰£៛₽₹₨₪৳₸₮₩¥]+/g,""). Por cierto, no veo el backtick (`) en ningún lado, ¿cómo es que?
Rolf
Está perdido. Parece difícil encontrar una lista de todos los signos de puntuación.
Alex
1

Si desea retener solo alfabetos y espacios, puede hacer:

str.replace(/[^a-zA-Z ]+/g, '').replace('/ {2,}/',' ')
codictorio
fuente
8
¿No sacará eso más que solo la puntuación? Unicode y similares?
Alex
3
¿Quieres decir que "sólo inglés alfabetos y espacios"
Rolf
0

Depende de lo que intente devolver. Usé esto recientemente:

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