Регулярное выражение для удаления букв без буквы, но сохраняйте буквы с акцентом

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

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

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

Ответ 1

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

Вот пример, который разбивает нелатинские словарные символы из строки: 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, "");

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

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

Ответ 2

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

var desired = stringToReplace.replace(/[-''[email protected]#$%^&*()_|+=?;:'",.<>\{\}\[\]\\\/]/gi, '')

Ответ 3

Заметка! Работает только для 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".

Чтобы сопоставить нецифровые или небуквенные символы для их удаления, напишите a ^ как первый символ после открытия скобки [ и prepend / и append +/.

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

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

Поскольку Javascript не имеет регулярных выражений Unicode, я написал программу Python для итерации по всему Юникоду и фильтрации по имени 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.

Просмотрите базу данных символов Юникода, чтобы просмотреть имена всех символов Юникода. Имя находится в верхнем регистре после первой точки с запятой, например, для 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)

Ответ 4

var desired = stringToReplace.replace(/[\u0000-\u007F][\W]/gi, '');

может сделать трюк.

См. Также этот вопрос Javascript + Unicode regexes.

Ответ 6

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

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

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

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

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

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

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

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