Допустим, в 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, '');
Итак, все диакритические символы находятся в приведенном выше шаблоне регулярного выражения, и как мы можем использовать приведенный выше шаблон регулярного выражения или изменить его, чтобы использовать его в тексте, заменяя регулярное выражение вместе с динамической переменной, как описано выше.
const resultString = 'اَلْيَوْمُ جَمِيلٌ وَالشَّمْسُ';const searchText = 'والشم'; допустим, у нас есть приведенный выше текст на арабском языке, мы хотим сделать то же самое с указанными выше переменными. ниже приведено регулярное выражение, которое фактически заменяет все диакритические знаки в арабском тексте пустой строкой и, таким образом, очищает все диакритические знаки: 'وَالشَّمْسُ'.normalize('NFD').replace(/([^\u0621-\u063A\u0641-\u064A\u0660-\u0669a-zA-Z 0-9])/g, ''); итак, как мы можем использовать приведенный выше шаблон регулярного выражения, чтобы мы могли игнорировать все диакритические знаки и обернуть searchText HTML-тегами на арабском языке поскольку это подстрока из resultString.
@bobblebubble ожидаемый результат будет: "اَلْيَوْمُ جَمِيلٌ <span class = "highlighted">وَالشَّم</span>سُ"
Подумайте о том, чтобы отредактировать свой вопрос или задать новый вопрос и указать точные требования (арабский текст, символы, которые следует игнорировать), а также вводные данные и ожидаемый результат.
@bobblebubble, вопрос сейчас отредактирован.
@bobblebubble прилагаемая демо-версия не работает со следующим: const searchText = 'قل اعوذ';const resultText = 'قُلْ أَعُوذُ بِرَبِّ النَّاسِ';
Ваш образец содержит не только диакритические знаки, но и буквы, например, أ (алеф с хамзой выше) , который по своему характеру отличается от ا. Ваш normalize('NFD') будет делать то, что должен, но, чтобы соответствовать обоим, я думаю, вам нужно будет построить карту регулярных выражений для всего, что может произойти, и заменить их, например, на [أا...], дополнительно в \p{M}*, как в связанном ответе. Дальше помочь не могу, может кто-то другой. Есть идея удалить и сделать репост? Однако удачи!
Я нашел этот ответ , который содержит список арабских символов, и обнаружил, что символы, которые необходимо сопоставить с одним экземпляром, вероятно, [اأإآ], [ؤئ], верно?
Я немного помолчал и попытался что-нибудь смастерить, надеюсь, это поможет! Кроме того, я попытался улучшить заголовок вашего вопроса, чтобы его было легче найти, чтобы вы могли получить другие варианты, пожалуйста, проверьте и отредактируйте, если они не подходят. Хорошего воскресенья.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Чтобы добиться желаемого результата — обернуть совпавшее слово тегами 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 часто содержит латинские цифры и буквы, вы можете настроить таргетинг только на арабские символы с помощью (?=[ء-ي٠-٩])|(?<=[ء-ي٠-٩]).
Ссылка
Спасибо, чувак, я очень ценю время и усилия, которые ты вложил в решение проблемы. иншаАллах, попробуем решение и тщательно его проверим. да наставит тебя Аллах!
Вы можете сделать что-то вроде searchText.replace(/\B/g,'\.?') (демо)