JavaScript функция для преобразования псевдо-алфавита Unicode в обычные символы? - PullRequest
2 голосов
/ 06 января 2020

Я пытаюсь написать функцию, которая принимает любую строку, содержащую символы в псевдо-алфавитах юникода, и возвращает эквивалентную строку, где такие символы были заменены обычными символами, найденными в ASCII.

const toRegularCharacters = s => {
  // ?
};

toRegularCharacters('ⓗⓔⓛⓛⓞ, ⓦⓞⓡⓛⓓ'); // "hello, world"
toRegularCharacters('?????, ?????'); // "hello, world"
toRegularCharacters('ん乇レレo, wo尺レd'); // "hello, world"

Я не хочу сам писать справочную таблицу. Я посмотрел на различные библиотеки "slugify", но они удаляют только акценты et c. В идеале функция должна работать в Node и браузере.

Конечно, не каждый специальный символ будет иметь обычный эквивалент. Решение должно сделать разумное предположение в этих случаях (например, "尺" -> "R"). Это должно работать безупречно для псевдо-алфавитов с «истинными преобразованиями»:

Текущие истинные преобразования: обведены, отрицательные обведены, азиатские во всю ширину, математические полужирные, математические полужирные Fraktur, математические полужирные итальянские c, математический жирный шрифт, математический двойной штрих, математический моноширин, математический без засечек, математический без засечек жирный, математический без засечек жирный италий c, математический без засечек италийский c, скобки, символы региональных индикаторов, в квадрате, минус в квадрате и тегирование текста (невидимое для скрытых тегов метаданных).

Как мне go о this?


Переход от "обычной" строки к псевдо-алфавитной реализован здесь: https://qaz.wtf/u/convert.cgi?text=hello%2C+world

Ответы [ 2 ]

2 голосов
/ 06 января 2020

Вы можете написать свой код для запроса базы данных Unicode, которую вы можете загрузить из Консорциума Unicode (или запросить с помощью символьной утилиты , но предположительно с ограниченной скоростью). База данных включает в себя такие вещи, как то, что глифы являются «смешиваемыми» для других глифов.

Например, ваш ? из ?????, ????? равен U + 1D4F1 , который имеет лотов с ошибками, одна из которых, конечно, стандартная латинская строчная h ( U + 0068 ). Таким образом, вы можете go просмотреть каждый символ во входной строке, найти его, и, если он имеет латинскую букву az (также может быть 0-9), заменить ее на это.

Не будет быть идеальным Как указала Дечезе, не перечисляет никаких путаниц, даже если она выглядит неопределенно как «h» для читателя Engli sh. Также не . Поэтому вам, возможно, придется дополнить свой собственный поиск, даже если вы сказали, что не хотите (или просто живете с несовершенством).

1 голос
/ 06 января 2020

Следуя предложению этого ответа , в этом решении используется пакет unicode-12.1.0 NPM:

const unicodeNames = require('unicode-12.1.0/Names');

const overrides = Object.freeze({
  'ん': 'h',
  '乇': 'E',
  'レ': 'l',
  '尺': 'r',
  // ...
});

const toRegularCharacters = xs => {
  if (typeof xs !== 'string') {
    throw new TypeError('xs must be a string');
  }

  return [ ...xs ].map(x => {
    const override = overrides[x];

    if (override) {
      return override;
    }

    const names = unicodeNames
      .get(x.codePointAt(0))
      .split(/\s+/);

    // console.log({
    //   x,
    //   names,
    // });

    const isCapital = names.some(x => x == 'CAPITAL');

    const isLetter = isCapital || names.some(x => x == 'SMALL');

    if (isLetter) {
      // e.g. "Ŧ" is named "LATIN CAPITAL LETTER T WITH STROKE"
      const c = names.some(x => x == 'WITH') ?
        names[names.length - 3] :
        names[names.length - 1];

      return isCapital ?
        c :
        c.toLowerCase();
    }

    return x;
  }).join('');
};

console.log(
  toRegularCharacters('??.??????.??')
);

console.log(
  toRegularCharacters('????-???')
);

console.log(
  toRegularCharacters('ん乇レレo, wo尺レd')
);

console.log(
  toRegularCharacters('ŦɆSŦƗNǤ')
);

Таблица данных Names содержит необходимую информацию, но не в лучшей форме, так что есть некоторая хакерская манипуляция со строками, чтобы вывести персонажа

Карта переопределений используется для таких случаев, как '尺'.

Лучшее решение - извлечь свойство idn_mapping, как упомянуто @Seth.

...