我有一个移动设备名称列表,如
"Sony Xperia Z1 Compact"
"Samsung Galaxy Trend Plus"
"Samsung Galaxy Tab 2"
我需要一个正则表达式来创建这些字符串中的标签,以便以这种方式匹配连续的单词(预期结果):
["Sony", "Sony Xperia", "Sony Xperia Z1", "Sony Xperia Z1 Compact"]
我尝试了一些积极向前看的东西:
/(?=([a-z]+\s+[a-z]+))[a-z]+/i
我获得了:
model = "Samsung Galaxy Trend Plus"
"Samsung Galaxy Trend Plus"
model.match(/(?=([a-z]+\s+[a-z]+))[a-z]+/i)
["Samsung", "Samsung Galaxy"]
但是当你有一个单词时,这不起作用,因此,在添加一个可选组后:
/(?=([a-z]+\s+[a-z]+))|[a-z]+/i
我获得了:
model = "Samsung"
"Samsung"
model.match(/(?=([a-z]+\s+[a-z]+))|[a-z]+/i)
["Samsung", undefined]
所以,试图概括:
/(?=([a-z]+\s+[a-z]+))(?=([a-z]+\s+[a-z]+\s+[a-z]+))(?=([a-z]+\s+[a-z]+\s+[a-z]+\s+[a-z]+))[a-z]+/i
我得到了
"Samsung Galaxy Trend Plus"
model.match(/(?=([a-z]+\s+[a-z]+))(?=([a-z]+\s+[a-z]+\s+[a-z]+))(?=([a-z]+\s+[a-z]+\s+[a-z]+\s+[a-z]+))[a-z]+/i)
["Samsung", "Samsung Galaxy", "Samsung Galaxy Trend", "Samsung Galaxy Trend Plus"]
并且应该有 N 字,如何使这个正则表达式通用( N 字变量的自由度)?
另外,如何摆脱undefined
?正如here所解释的那样,我应该使用非捕获组,因此这会阻止我以我的方式捕获连续的单词。
答案 0 :(得分:3)
对于那些有类似问题但又不想(ab)使用正则表达式的人:
name = "Samsung Galaxy Trend Plus";
result = name.split(/\s+/g).map(function(_, i, a) {
return a.slice(0, i + 1).join(" ")
});
document.write(result);
答案 1 :(得分:1)
我可以建议几乎纯粹的正则表达式解决方案。几乎是因为我需要交换单词顺序以获得正确的输出子短语:
var re = /(?=\b((?:\S+[ \t]*)+))/g;
var str = 'Sony Xperia Z1 Compact';
str = str.split(' ').reverse().join(' ');
while ((m = re.exec(str)) !== null) {
if (m.index === re.lastIndex) {
re.lastIndex++;
}
document.getElementById("t").innerHTML += m[1].split(' ').reverse().join(' ') + "<br/>";
}
<div id="t"/>
(?=\b((?:\S+[ \t]*)+))
正则表达式捕获所有非空白字符块,后跟可选空格(但不是换行符号),我们确保只使用\b
字边界获得整个单词。
我认为很难在没有倒车的情况下获得它,因为我们在JS中没有可变宽度的外观。
答案 2 :(得分:0)
虽然这不会帮助OP,因为他们在评论中表示它必须&#39;是一个正则表达式的解决方案,使用javascript实现这一目标的一种快捷方法是将字符串拆分为空格字符,然后在循环中重建另一个数组:
var s = 'Sony Xperia Z1 Compact';
var a = s.split(' ');
var b = [], c = [];
for(var i=0; i < a.length; i++) {
b.push(a[i]);
c.push(b.join(' '));
}
c.toString();
=
Sony,Sony Xperia,Sony Xperia Z1,Sony Xperia Z1 Compact
请参阅demo here