首页 > 解决方案 > 从Nodejs中的字符串替换乌尔都语单词

问题描述

我想对乌尔都语单词执行替换字符串操作,但以下代码没有替换آپaap. 我正在使用单词边界,以便它替换整个单词而不是单词的一部分。

var str ="آپ کا نام کیا ہے؟";
var res = str.replace(/\bآپ\b/g, "aap");
console.log(res);

我期望以下输出:

 کا نام کیا ہے؟ aap

标签: javascriptregexstringunicodereplace

解决方案


\b恐怕是以英语为中心的,而且实际上并不擅长以英语为中心。:-) (例如,它将匹配“以英语为中心”中“英语”的末尾。)

您可以使用带有否定 Unicode“字母”类别的环视来检查单词边界。这些功能存在于最新的 JavaScript 规范中,但支持非常参差不齐。不过,您可以向它扔一个图书馆:XRegExpSteven Levithan:

var str ="آپ کا نام کیا ہے؟";
var rex = XRegExp("(?<=^|[^\\p{Letter}])آپ(?=$|[^\\p{Letter}])", "g");
var res = str.replace(rex, "aap");
console.log(res);
<script src="https://cdnjs.cloudflare.com/ajax/libs/xregexp/3.2.0/xregexp-all.min.js"></script>

在那个正则表达式中:

  • (?<=^|[^\p{Letter}])根据 Unicode 标准,是输入开始或非字母的后视。(请注意,\必须在我们传递的字符串中转义,XRegExp以便XRegExp接收它,因为它\是字符串文字中的转义。)
  • آپ是这个词
  • (?=$|[^\p{Letter}])是对输入结尾或非字母的前瞻。(再次,\在字符串中转义。)

正如我在评论中提到的,由于从右到左 (RTL) 与从左到右 (LTR) 的语言脚本差异(例如,阿拉伯文字与拉丁文字),这显示为aap کا نام کیا ہے؟而不是您的预期输出,即使文本被替换在正确的位置,因为乌尔都语单词位于字符串的开头(但在渲染时,所有的阿拉伯语脚本都是从右到左输出的)。因此,在更新后的字符串中,从左到右输出拉丁文字 ( app),然后从右到左输出阿拉伯文字。

在一个真正最新的 JavaScript 引擎中,您可以在本地执行它:

var str ="آپ کا نام کیا ہے؟";
var rex = /(?<=^|[^\p{Letter}])آپ(?=$|[^\p{Letter}])/g;
var res = str.replace(rex, "aap");
console.log(res);
<script src="https://cdnjs.cloudflare.com/ajax/libs/xregexp/3.2.0/xregexp-all.min.js"></script>

例如,这适用于 Chrome v75 和 Node.js v12.4 中的 V8 版本。

(旁注:使用XRegExp,您可以使用简写\pL代替\p{Letter},但不能使用 JavaScript 自己的正则表达式。)


推荐阅读