Regex для удаления не буквенных символов, но с акцентом на буквы - PullRequest
12 голосов
/ 01 декабря 2011

У меня есть строки на испанском и других языках, которые могут содержать общие специальные символы, такие как (), * и т. Д., Которые мне нужно удалить.Но проблема в том, что он также может содержать специальные языковые символы, такие как -, á, ó, í и т. Д., И они должны оставаться.Поэтому я пытаюсь сделать это с помощью регулярного выражения следующим образом:

var desired = stringToReplace.replace(/[^\w\s]/gi, '');

К сожалению, он удаляет все специальные символы, включая язык.Не уверен, как этого избежать.Может быть, кто-то может предложить?

Ответы [ 6 ]

12 голосов
/ 16 октября 2012

Я бы предложил использовать превосходную библиотеку Стивена Левитана XRegExp и ее плагин Unicode .

Вот пример, который удаляет символы нелатинского слова из строки: http://jsfiddle.net/b3awZ/1/

var regex = XRegExp("[^\\s\\p{Latin}]+", "g");
var str = "¿Me puedes decir la contraseña de la Wi-Fi?"
var replaced = XRegExp.replace(str, regex, "");

См. Также этот ответ самого Стивена Левитана:

Регулярное выражение испанских и арабских слов

8 голосов
/ 01 декабря 2011

Вместо того, чтобы принимать символы из белого списка, которые вы принимаете, вы можете попробовать занести в черный список недопустимые символы:

var desired = stringToReplace.replace(/[-'`~!@#$%^&*()_|+=?;:'",.<>\{\}\[\]\\\/]/gi, '')
7 голосов
/ 19 октября 2012

Примечание! Работает только для 16-битных кодовых точек. Этот ответ неполон.

Краткий ответ

Класс символов для всех арабских цифр и латинских букв : [0-9A-Za-z\u00c0-\u00d6\u00d8-\u00f6\u00f8-\u02af\u1d00-\u1d25\u1d62-\u1d65\u1d6b-\u1d77\u1d79-\u1d9a\u1e00-\u1eff\u2090-\u2094\u2184-\u2184\u2488-\u2490\u271d-\u271d\u2c60-\u2c7c\u2c7e-\u2c7f\ua722-\ua76f\ua771-\ua787\ua78b-\ua78c\ua7fb-\ua7ff\ufb00-\ufb06].

Чтобы получить регулярное выражение, используйте /^ и добавьте +$/. Это будет соответствовать строки, состоящие только из латинских букв и цифр, таких как "mérito" или "Schönheit".

Чтобы сопоставить нецифровые или небуквенные символы для их удаления, введите ^ в качестве первого символа после открывающей скобки [, добавьте / и добавьте +/.

Как я узнал об этом? Продолжить чтение.

Длинный ответ: используйте метапрограммирование!

Поскольку Javascript не имеет регулярных выражений Unicode, я написал программу на Python для перебора всего Unicode и фильтрации по имени Unicode. Трудно сделать это правильно вручную. Почему бы не позволить компьютеру выполнять грязную и черную работу?

import unicodedata
import re
import sys

def unicodeNameMatch(pattern, codepoint):
  try:
    return re.match(pattern, unicodedata.name(unichr(codepoint)), re.I)
  except ValueError:
    return None

def regexChr(codepoint):
  return chr(codepoint) if 32 <= codepoint < 127 else "\\u%04x" % codepoint

names = sys.argv
prev = None

js_regex = ""
for codepoint in range(pow(2, 16)):
  if any([unicodeNameMatch(name, codepoint) for name in names]):
    if prev is None: js_regex += regexChr(codepoint)
    prev = codepoint
  else:
    if not prev is None: js_regex += "-" + regexChr(prev)
    prev = None

print "[" + js_regex + "]"

Вызовите это так: python char_class.py latin digit и вы получите класс персонажей, упомянутый выше. Это ужасный класс char, но вы точно знаете, , что вы перехватили все символы, имена которых содержат latin или digit.

Просмотр базы данных символов Unicode для просмотра имен всех символов Unicode. Имя находится в верхнем регистре после первой точки с запятой, например, для A это строка

0041;LATIN CAPITAL LETTER A;Lu;0;L;;;;;N;;;;0061;

Попробуйте python char_class.py "latin small", и вы получите класс символов для всех латинских строчных букв.

Редактировать : Существует небольшая ошибка (или ошибка) в том, что \u271d-\u271d происходит в регулярном выражении. Возможно, это исправление поможет: заменить

if not prev is None: js_regex += "-" + regexChr(prev)

от

if not prev is None and prev != codepoint: js_regex += "-" + regexChr(prev)
1 голос
/ 21 октября 2012

Если вы настаиваете на внесении белых списков, вот самый простой способ сделать это:

Проверить, содержит ли строка только буквы (az + é ö å å ø ø и т. Д.)

Работает, отслеживая все буквы в юникоде.

1 голос
/ 01 декабря 2011
var desired = stringToReplace.replace(/[\u0000-\u007F][\W]/gi, '');

может добиться цели.

См. Также регулярные выражения Javascript + Unicode вопрос.

0 голосов
/ 17 октября 2012

К сожалению, Javascript не поддерживает Свойства символов Unicode (что было бы для вас подходящей функцией регулярных выражений).Если изменение языка является опцией для вас, PHP (например) может сделать это:

preg_replace("/[^\pL0-9_\s]/", "", $str);

Где \pL соответствует любому символу Unicode, который представляет букву (нижний регистр, верхний регистр, измененный или неизмененный)).

Если вам нужно придерживаться JavaScript и вы не можете использовать библиотеку, предложенную Тимом Дауном, единственными вариантами, вероятно, являются либо черный, либо белый список.Но ваша награда упоминает, что внесение в черный список на самом деле не вариант в вашем случае.Таким образом, вам, вероятно, просто нужно будет вручную включить специальные символы из соответствующего языка.Таким образом, вы можете просто сделать это:

var desired = stringToReplace.replace(/[^\w\sñáóí]/gi, '');

или использовать соответствующие им последовательности Unicode:

var desired = stringToReplace.replace(/[^\w\s\u00F1\u00C1\u00F3\u00ED]/gi, '');

Затем просто добавьте все те, о которых вы хотите позаботиться.Обратите внимание, что модификатор без учета регистра также работает с последовательностями Unicode.

...