Я должен соответствовать в текстовом документе границы слов для слов, имеющих диакритические знаки. Учитывая токен word
, мое регулярное выражение выглядит как
var wordRegex = new RegExp("\\b(" + word + ")\\b", "g");
while ((match = wordRegex.exec(text)) !== null) {
if (match.index > (seen.get(token) || -1)) {
var wordStart = match.index;
var wordEnd = wordStart + token.length - 1;
item.characterOffsetBegin = wordStart;
item.characterOffsetEnd = wordEnd;
seen.set(token, wordEnd);
break;
}
}
Это работает нормально для обычных слов, таких как ciao
, casa
и т. Д. Но это не сработает, когда в тексте есть такие слова, как però
, così
и т. Д.
const seen = new Map();
var text = "Ci son macchine nascoste e, però, nascoste male"
var tokens = text.split(/[^a-zA-Z0-9àèéìíîòóùúÀÈÉÌÍÎÒÓÙÚ]+/i)
tokens.forEach((token, tokenIndex) => {
var item = {
"index": (tokenIndex + 1),
"word": token
}
var escaped = token.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&");
var wordRegex = new RegExp("\\b(" + escaped + ")\\b", "g");
var match = null;
console.log(token, "---->", wordRegex)
while ((match = wordRegex.exec(text)) !== null) {
console.log("\t---->", match.index)
if (match.index > (seen.get(token) || -1)) {
var wordStart = match.index;
var wordEnd = wordStart + token.length - 1;
item.characterOffsetBegin = wordStart;
item.characterOffsetEnd = wordEnd;
seen.set(token, wordEnd);
break;
}
}
})
Вы можете видеть, как в то время как некоторые слова (например, macchine
или nascoste
) совпадают, поэтому я получаю match.index
, для других слов (например, però
) регулярное выражение не работает должным образом и match
переменная null
:
macchine ----> /\b(macchine)\b/g
----> 7
nascoste ----> /\b(nascoste)\b/g
----> 16
e, ----> /\b(e\,)\b/g
però, ----> /\b(però\,)\b/g
nascoste ----> /\b(nascoste)\b/g
----> 16
----> 34
Как написать граничное регулярное выражение, которое тоже поддерживает диакритические знаки?
[UPDATE]
Следуя подходу, предложенному в комментариях, я использовал удаление диакритических знаков для каждого слова token
перед применением Regex
, а затем ко всему text
, например:
var normalizedText = removeDiacritics(text);
// for each token...
var escaped = token.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&");
escaped = removeDiacritics(escaped);
var wordRegex = new RegExp("\\b(" + escaped + ")\\b", "g");
var match = null;
while ((match = wordRegex.exec( normalizedText )) !== null)
{
//...
и на этот раз я получу слова с акцентами, захваченными границами слов \b
. Конечно, этот подход не оптимален, потому что removeDiacritics
должен применяться для каждого токена, поэтому лучшим решением будет сделать это один раз.