我有一个字符串“hello @steph你要求的电子邮件是test@test.com用户@test”
我想把它变成:
['hello ', <a href="">@steph</a>, 'the email you requested is test@test.com for user ', <a href="">@test</a>];
这就是我所拥有的:
function matchUserMention(text) {
var pattern = /\B@[a-z0-9_-]+/gi;
return text.match(pattern); // [@steph, @test]
}
function applyUser(string) {
let text = string;
if (typeof text != 'string') return text;
var arr = [];
function replaceAll(str, find, replace) {
return text.replace(new RegExp(find, 'g'), replace);
}
const matches = matchUserMention(text);
_.each(matches, (match) => {
text = replaceAll(text, match, <a href={'https://test.co'}>${match}</a>);
});
return text;
}
文本现在返回:
'hello <a href="">@steph</a>, the email you requested is test@test.com for user <a href="">@test</a>
有谁知道从这里创建阵列的最佳方法?因为我需要一直调用它,所以不能重要
答案 0 :(得分:1)
您可以将split
与包含捕获组的正则表达式一起使用。这将导致数组在奇数索引处具有匹配元素。然后,您可以通过<a>
将.map()
换行应用于那些换行符。最后,您可以使用.filter()
删除空字符串(例如,在数组的开头或结尾):
// Sample data
var url = 'https://elk.co';
var string = "hello @steph the email you requested is test@test.com for user @test";
// The transformation
var parts = string.split(/(\B@[\w-]+)/g)
.map( (w,i) => i%2 ? `<a href='${url}'>${w}</a>` : w )
.filter(Boolean);
// Output the result
console.log(parts);
&#13;
答案 1 :(得分:1)
function applyUser(string) {
const reg = /\B@[a-z0-9_-]+/ig;
const res = [];
let match;
// loop while we can match something
while((match = reg.exec(string)) !== null) {
// push to result array portion of string before user match, if any
if (match.index > 0) {
res.push(string.substring(0, match.index));
}
// push updated user name to result array
res.push('<a href="">' + match[0] + '</a>');
// remove processed part from a string
string = string.substr(match.index + match[0].length);
}
// push any reminder to the result array
if (string) {
res.push(string);
}
return res;
}
答案 2 :(得分:0)
此方法与用户名匹配并使用RegExp capability of remembering the last match postion。因此,后续exec()
调用将匹配后续用户名。 exec()
返回的匹配对象是一个包含匹配文本和指向匹配位置的index
属性的数组。
代码将文本从最后一个位置(最初位置0)复制到匹配的用户名,然后附加“包装”用户名并重新开始,直到没有更多的用户名匹配。
代码逐行注释,描述其功能:
function wrapUsernames(str) {
// match "usernames" ("at" followed by text, preceeded by non-word character or line-start),
// the RegExp keeps its state
var re = /(?:([^\w]|^)(@[a-z]+))/g,
// store a RegExp match object
match,
// store the text fragments
results = [],
// remember last index for substring copy
lastIndex = 0;
// match and store result, returns null if it does no longer match
while (match = re.exec(str)) {
// copy text from last match / start to username
// (only if not matched at index 0 to prevent empty string)
if (match.index != 0) {
results.push( str.substring(lastIndex, match.index) );
}
if (match[1].length >= 1) {
// it also matched the char before the username, append it
results.push(match[1]);
}
// copy matched username and wrap in a tag
results.push('<a href="...">' + match[2] + '</a>');
// update the index to start copy at the next position
lastIndex = match.index + match[0].length;
}
// append the remaining string (only if it wouldn't be an empty string)
if (lastIndex < str.length) {
results.push(str.substring(lastIndex));
}
return results;
}
这也应匹配前缀为空格以外的其他字符的用户名:
> wrapUsernames("(@steph) the email you requested is test@test.com for user (@test)")
< Array [ "(", "<a href="...">@steph</a>", ") the email you requested is test@test.com for user ", "(", "<a href="...">@test</a>", ")" ]
> wrapUsernames("@steph the email you requested is test@test.com for user (@test)")
< Array [ "<a href="...">@steph</a>", " the email you requested is test@test.com for user ", "(", "<a href="...">@test</a>", ")" ]
> wrapUsernames("hi, @steph the email you requested is test@test.com for user @test")
< Array [ "hi,", " ", "<a href="...">@steph</a>", " the email you requested is test@test.com for user ", " ", "<a href="...">@test</a>" ]
答案 3 :(得分:0)
谢谢大家,这最终成了我用过的,以防万一。这是其他回复的混合。
function applyUser(str) {
var arr = [],
userRegEx = /\B@[a-z0-9_-]+/gi,
execResult,
lastFoundLen = 0,
found,
strLen = str.length,
index = 0;
while ((execResult = userRegEx.exec(str)) !== null) {
const newIndex = execResult.index;
if (newIndex > index + lastFoundLen) arr.push(str.substring(index + lastFoundLen, newIndex));
found = execResult[0];
if (!found) break;
const foundLen = found.length;
const userId = execResult[0].substring(1);
arr.push(
<ProfilePersona
key={userId}
noAvatar
view="compact"
userId={userId}>
{userId}
</ProfilePersona>
);
index = newIndex;
lastFoundLen = foundLen;
}
if (index + lastFoundLen < strLen) arr.push(str.substr(index + lastFoundLen));
if (!arr.length) arr.push(str);
return arr;
}