regex JavaScript正则表达式获取句子中每个单词的第一个字符(波斯语和英语句子)

koaltpgm  于 2023-11-20  发布在  Java
关注(0)|答案(5)|浏览(188)

假设我有以下字符串:

var englishSentence = 'Hellow World';
var persianSentence = 'گروه جوانان خلاق';

字符串
对于英语,我使用从以下正则表达式,但我怎么能写一个正则表达式来支持波斯语,或他们的混合。

var matches = englishSentence.match(/\b(\w)/g);
  acronym = matches.join('');

xuo3flqw

xuo3flqw1#

根本原因

无法匹配Unicode字边界,即使在ECMA 2018中,\b也不支持Unicode。

解决方案

对于兼容ECMA 2018的浏览器(例如截至2018年4月的最新版本的Chrome),您可以用途:

var englishSentence = 'Hellow World';
var persianSentence = 'گروه جوانان خلاق';
var reg = /(?<!\p{L}\p{M}*)\p{L}\p{M}*/gu;
console.log(englishSentence.match(reg));
console.log(persianSentence.match(reg));

字符串

详情

  • (?<!\p{L}\p{M}*)-如果Unicode字母后跟0+附加符号,则匹配失败的负向后查找
  • \p{L}\p{M}*-Unicode字母,后跟0+附加符号
  • gu-g-全局,搜索所有匹配项,u-使模式支持Unicode。

如果您需要在旧版/其他浏览器中使用相同的功能,请使用XRegExp

function getFirstLetters(s, regex) {
  var results=[], match;
  XRegExp.forEach(s, regex, function (match, i) {
    results.push(match[1]);
  });
  return results;
}
var rx = XRegExp("(?:^|[^\\pL\\pM])(\\pL\\pM*)", "gu");
console.log(getFirstLetters("Hello world", rx));
console.log(getFirstLetters('گروه جوانان خلاق', rx));
<script src="https://cdnjs.cloudflare.com/ajax/libs/xregexp/3.2.0/xregexp-all.js"></script>

的数据

详情

  • (?:^|[^\\pL\\pM])-匹配字符串开头(^)或Unicode字母或变音符号以外的任何字符的非捕获组
  • (\\pL\\pM*)-组1:任何Unicode字母后跟0+变音符号。

在这里,我们需要提取组1的值,因此每次匹配时.push(match[1])

xurqigkl

xurqigkl2#

您可以按空格分割,然后获取每个项目的第一个字符

var output = sentence.split( /\s+/ ).map( s => s.charAt(0) ).join("")

字符串

Demo

var fnGetFirstChar = (sentence) => sentence.split( /\s+/ ).map( s => s.charAt(0) ).join("");

var englishSentence = 'Hellow World';
var persianSentence = 'گروه جوانان خلاق';

console.log( fnGetFirstChar( englishSentence ) );

console.log( fnGetFirstChar( persianSentence ) );

yvt65v4c

yvt65v4c3#

如果你在代码中这样做,一种方法是用

(?:\s|^)(\S)

字符串
它匹配前面有白色空格或字符串开头(\s|^)的非白色空格字符(\S),将非白色空格字符捕获到捕获组1。

var sentence  = 'Hello World\n'+
                'گروه جوانان خلاق',
    re        = /(?:\s|^)(\S)/g,
    result = '';
    
while( m = re.exec(sentence) )
{
  result += m[1];
};

console.log( result );

2sbarzqh

2sbarzqh4#

最好使用从آی沿着的字符范围和a-z,因为JS中的单词边界不能识别多字节字母,而在大多数风格中它可以。

console.log(
  "سلام حالت چطوره؟".match(/( |^)[آ-یa-z](?=[آ-یa-z])/gi).map(x => x.trim()).join('')
)

console.log(
  "این یک test است".match(/( |^)[آ-یa-z](?=[آ-یa-z])/gi).map(x => x.trim()).join('')
)

字符串
细分:

  • (?: |^)匹配输入字符串的空格或开头
  • [آ-ی]匹配波斯语中的字符
  • (?=启动积极的前瞻
  • [آ-ی]如果后跟另一个波斯语字符
  • )正向前瞻结束

注意事项:字符范围从到有超过波斯语字母(一些阿拉伯字母也)的精确匹配(我怀疑你是否在任何地方使用这些字母)使用一个坚实的字符类:

[اآبپتثجچحخدذرزژسشصضطظعفقگکلمنوهی]

console.log(
    "سلام دوست من".match(/( |^)[اآبپتثجچحخدذرزژسشصضطظعفقگکلمنوهیa-z](?=[اآبپتثجچحخدذرزژسشصضطظعفقگکلمنوهیa-z])/gi).map(x => x.trim()).join('')
)

jgzswidk

jgzswidk5#

在JS中,你可以模拟一个单词边界。
可能相关的是,您可以通过启用引擎Unicode选项并使用属性[\p{L}\p{N}_]来定义一个单词,然后只需对左/右边界进行数学运算。

/(?:(?<![\p{L}\p{N}_])(?=[\p{L}\p{N}_])|(?<=[\p{L}\p{N}_])(?![\p{L}\p{N}_]))/gu

字符串
这是一个韩语示例,但适用于任何Unicode。
https://regex101.com/r/Mjttej/1

(?:                           # Cluster start
   (?<! [\p{L}\p{N}_] )          # Lookbehind assertion for a char that is NOT a word
   (?= [\p{L}\p{N}_] )           # Lookahead assertion for a char that is IS a word
   
 |                              # or,
   
   (?<= [\p{L}\p{N}_] )          # Lookbehind assertion for a char that is IS a word
   (?! [\p{L}\p{N}_] )           # Lookahead assertion for a char that is NOT a word
                                 # -------
)                             # Cluster end

相关问题