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

Допустим, в javascript есть арабские строки:

const resultText = 'اَلْيَوْمُ جَمِيلٌ وَالشَّمْسُ';
const searchText = 'والشم';

Переменная searchText является динамической и может иметь другое значение во время выполнения. Итак, нам нужно написать регулярное выражение, которое заменит searchText в resultText, но проблема в том, что наряду с необходимостью написания регулярного выражения с динамической переменной также нужно игнорировать определенные символы при сопоставлении, а эти символы, которые нужно игнорировать, являются диакритическими знаками в Арабский. Таким образом, конечный результат будет после замены строки следующим образом:

"اَلْيَوْمُ جَمِيلٌ <span class = "highlighted">وَالشَّم</span>سُ"

поэтому в основном мы хотим обернуть слово searchText тегом HTML span, но при этом хотим игнорировать диакритические знаки, чтобы иметь соответствие для замены, потому что searchText будет без диакритических знаков, а resultText будет с диакритическими знаками, если мы сначала удалим все диакритические знаки в resultText, тогда мы легко получим совпадение, но хотим сохранить диакритические знаки в resultText и по-прежнему успешно сопоставлять, поэтому для этого нужно будет игнорировать диакритические знаки при сопоставлении searchText внутри него.

На данный момент нам удалось обернуть совпадающее слово в HTML, но игнорирование диакритических знаков остается:

const searchText = 'والشم';

const resultText = 'اَلْيَوْمُ جَمِيلٌ وَالشَّمْسُ';

const regex1 = new RegExp(this.searchText, 'gi');

const finalText = result.replace(regex1, '<span class = "highlighted">$&</span>');

Для подсказки: приведенное ниже регулярное выражение используется для очистки всех диакритических знаков из строки:

'وَالشَّمْسُ'.normalize('NFD').replace(/([^\u0621-\u063A\u0641-\u064A\u0660-\u0669a-zA-Z 0-9])/g, '');

Итак, все диакритические символы находятся в приведенном выше шаблоне регулярного выражения, и как мы можем использовать приведенный выше шаблон регулярного выражения или изменить его, чтобы использовать его в тексте, заменяя регулярное выражение вместе с динамической переменной, как описано выше.

Вы можете сделать что-то вроде searchText.replace(/\B/g,'\.?') (демо)

bobble bubble 02.06.2024 11:35
const resultString = 'اَلْيَوْمُ جَمِيلٌ وَالشَّمْسُ';const searchText = 'والشم'; допустим, у нас есть приведенный выше текст на арабском языке, мы хотим сделать то же самое с указанными выше переменными. ниже приведено регулярное выражение, которое фактически заменяет все диакритические знаки в арабском тексте пустой строкой и, таким образом, очищает все диакритические знаки: 'وَالشَّمْسُ'.normalize('NFD').replace(/([^\u0621-\u063A\u06‌​41-\u064A\u0660-\u06‌​69a-zA-Z 0-9])/g, ''); итак, как мы можем использовать приведенный выше шаблон регулярного выражения, чтобы мы могли игнорировать все диакритические знаки и обернуть searchText HTML-тегами на арабском языке поскольку это подстрока из resultString.
Muhammad Shahryar 05.06.2024 17:11

@bobblebubble ожидаемый результат будет: "اَلْيَوْمُ جَمِيلٌ <span class = "highlighted">وَالشَّم</span>سُ"

Muhammad Shahryar 06.06.2024 11:20

Подумайте о том, чтобы отредактировать свой вопрос или задать новый вопрос и указать точные требования (арабский текст, символы, которые следует игнорировать), а также вводные данные и ожидаемый результат.

bobble bubble 06.06.2024 11:51

@bobblebubble, вопрос сейчас отредактирован.

Muhammad Shahryar 07.06.2024 13:17
Уже есть очень похожий вопрос, надеюсь, он решается!
bobble bubble 07.06.2024 15:48

@bobblebubble прилагаемая демо-версия не работает со следующим: const searchText = 'قل اعوذ';const resultText = 'قُلْ أَعُوذُ بِرَبِّ النَّاسِ';

Muhammad Shahryar 07.06.2024 16:04

Ваш образец содержит не только диакритические знаки, но и буквы, например, أ (алеф с хамзой выше) , который по своему характеру отличается от ا. Ваш normalize('NFD') будет делать то, что должен, но, чтобы соответствовать обоим, я думаю, вам нужно будет построить карту регулярных выражений для всего, что может произойти, и заменить их, например, на [أا...], дополнительно в \p{M}*, как в связанном ответе. Дальше помочь не могу, может кто-то другой. Есть идея удалить и сделать репост? Однако удачи!

bobble bubble 07.06.2024 18:12

Я нашел этот ответ , который содержит список арабских символов, и обнаружил, что символы, которые необходимо сопоставить с одним экземпляром, вероятно, [اأإآ], [ؤئ], верно?

bobble bubble 08.06.2024 20:53
Демо JS
bobble bubble 08.06.2024 20:53

Я немного помолчал и попытался что-нибудь смастерить, надеюсь, это поможет! Кроме того, я попытался улучшить заголовок вашего вопроса, чтобы его было легче найти, чтобы вы могли получить другие варианты, пожалуйста, проверьте и отредактируйте, если они не подходят. Хорошего воскресенья.

bobble bubble 09.06.2024 12:44
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
3
11
176
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Чтобы добиться желаемого результата — обернуть совпавшее слово тегами HTML, игнорируя при этом определенные символы (например, точку в данном случае), вы можете изменить шаблон регулярного выражения, чтобы использовать утверждение отрицательного просмотра вперед. Вот как вы можете это сделать:

const searchText = 'thing';
const result = 'some th.in.g';
// Escape special characters in the search text
const escapedSearchText = searchText.replace(/[.*+?^${}()|[\]\\]/g, 
'\\$&');

// Construct the regular expression pattern with negative lookahead
const regex = new RegExp(`\\b${escapedSearchText.replace(/\./g, '\\.')} 
(?!\\.)\\b`, 'gi');

// Replace the matched word with HTML span tags
const finalText = result.replace(regex, '<span class = "highlighted">$& 
</span>');

console.info(finalText);
Ответ принят как подходящий

Помимо диакритических знаков в этом одном из ваших образцов (комментарий) есть даже символы без таких знаков, которые имеют вариации. ا (алеф) — это другой символ, чем أ (алеф с хамзой выше).

Для сопоставления вам потребуется идентифицировать все такие символы, которые могут встречаться , и заменить каждое их появление в вашем searchText классом символов, например заменить أ на [اأإآ].

Для начала я бы сделал что-то вроде этого (экспериментально, без опыта работы с арабским текстом).

// highlight arabic substring in text
function highlightArabic (search, text, verbose=false)
{
  // check input for at least one letter or digit
  if (!/[\p{L}\p{N}]/u.test(search) || !/[\p{L}\p{N}]/u.test(text)) {
    return text;
  } 
  
  // 1. normalize and remove special characters
  search = search.normalize('NFD').replace(/[^\p{L}\p{N}\s]+/gu, "");
  if (verbose) { console.info('s => ' + search); }

  // 2. multiple to one space, add optional unicode marks
  search = search.replace(/\s+/gu, " ").replace(/.{0}/gu, '\\p{M}*');

  // 3. diacritic-character variants, add variable space
  ['[اأإآ]','[وؤ]','[يئ]','\\s+'].forEach((v) => {
    search = search.replace(new RegExp(v, "gu"), v);
  });
  
  if (verbose) { console.info('p => ' + search); }
  let p = new RegExp(search, 'gui'); // i-flag if latin chars
  return text.replace(p,'<span class = "highlighted">$&</span>');
}

// test
s = 'والشم'; txt = 'اَلْيَوْمُ جَمِيلٌ وَالشَّمْسُ';
console.info(highlightArabic(s, txt, true));

s = 'قل اعوذ'; txt = 'قُلْ أَعُوذُ بِرَبِّ النَّاسِ'
console.info(highlightArabic(s, txt, true));

Обратите внимание, что я использовал .{0} для добавления \p{M}* между всеми символами. Если search часто содержит латинские цифры и буквы, вы можете настроить таргетинг только на арабские символы с помощью (?=[ء-ي٠-٩])|(?<=[ء-ي٠-٩]).

Ссылка

Спасибо, чувак, я очень ценю время и усилия, которые ты вложил в решение проблемы. иншаАллах, попробуем решение и тщательно его проверим. да наставит тебя Аллах!

Muhammad Shahryar 15.06.2024 21:48

Другие вопросы по теме