[英]Convert a string into an array of objects
目前我有这个字符串:
"Hello, I'm <%first%> <%last%>, and I <3 being a <%occupation%>. I am > blah";
如何将它分成一个 object 数组,如下所示:
[
{ type: 'string', value: 'Hello, I'm ' },
{ type: 'token', value: 'first' },
{ type: 'string', value: ' ' },
{ type: 'token', value: 'last' },
{ type: 'string', value: ', and I <3 being a ' },
{ type: 'token', value: 'occupation' },
{type: 'string', value: 'I am > blah'}
]
字符串的模式是,如果我们找到一个看起来像这样的单词:<%word%>,然后我们将它作为 object 类型放入数组中。 否则,我们将其作为类型字符串放入。 我的问题是我们如何在代码中实现它。
我很难形成将成为 key value
的value
的短语。 下面是我尝试实现的代码,但它是错误的。 我的想法是有一个单词变量,它是空的,当它通过字符串时,它会连接单词以形成阶段。 一旦它看到它在<%
和%>
之间,它将被赋予一个类型token
并推入arrStr
数组。
但是有两个问题:1)似乎使用此代码,正在生成从“H”到“He”到“Hel”到“Hell”到“Hello”的字符串的每次迭代。 2)它似乎从不接触令牌。 3) "hello" 中的第一个 "h" 以某种方式被省略了。
如何在不使用正则表达式的情况下做到这一点?
var str = "Hello, I'm <%first%> <%last%>, and I <3 being a <%occupation%>. I am > blah";
var arr = str.split('<%');
var final = [], vala, thetype;
arr.forEach(val => {
vala=val.split('%>');
thetype='string';
if (vala.length>0) thetype='token';
final.push({type: thetype, value: vala[0]});
})
我确信正则表达式会是一个更好的解决方案,但我不知道。 所以这是我的方法:
let txt = "Hello, I'm <%first%> <%last%>, and I <3 being a <%occupation%>. I am > blah"; var arr = []; txt.split("<%").forEach(x => { if (x.includes("%>")) { x.split("%>").forEach((y, i) => { arr.push({type: i == 0? 'token': 'string', value: y}); }) } else { arr.push({type: 'string', value: x}); } }); console.log(arr);
让我们使用一些虚拟字符串替换 angular 括号以轻松拆分数据。
因此,我们将<%
替换为*#
和%>
仅替换为*
。
然后我们只用*
split
数据。 拆分后我们有以下数组
[
"Hello, I'm ",
"#first",
" ",
"#last",
", and I <3 being a ",
"#occupation",
". I am > blah",
]
因此,我们仅在开始的 angular 括号中添加的额外#
将帮助我们区分标记和字符串。
现在我们可以简单地 map 这个数组并得到想要的结果。
注意:您可以使用确定不会出现在字符串中的适当虚拟字符串。
const str = "Hello, I'm <%first%> <%last%>, and I <3 being a <%occupation%>. I am > blah", res = str.replace(/<%/g, "*#").replace(/%>/g, "*").split("*").map((v) => v[0] === "#"? { type: "token", value: v.slice(1) }: { type: "string", value: v } ); console.log(res);
您可以使用这样的正则表达式解析字符串:
const input = "Hello, I'm <%first%> <%last%>, and I <3 being a <%occupation%>. I am > blah"; const regex = /<%([^%]+)%>/g; let result; let parsed = []; let lastIndex = 0; while(result = regex.exec(input)) { const { 1: match, index } = result; parsed.push({ type: 'string', value: input.substring(lastIndex, index) }); parsed.push({ type: 'token', value: match }); lastIndex = index + match.length + 4; } parsed.push({ type: 'string', value: input.substring(lastIndex) }); console.log(parsed);
使用正则表达式:
const convertToObjectArr = (str = '') => { const reg = /<%(.*?)%>/g; let arr = []; let index = 0, lastIndex = 0; while (match = reg.exec(str)) { index = match.index; if(index > lastIndex) { arr.push({ type: 'string', value: str.substring(lastIndex, index) }); } lastIndex = reg.lastIndex; arr.push({ type: 'token', value: str.substring(lastIndex-2, index+2) }); } if (lastIndex == 0) { arr.push({ type: 'string', value: str.substring(lastIndex) }); } else if (lastIndex < str.length) { arr.push({ type: 'token', value: str.substring(lastIndex) }); } return arr; } console.log( convertToObjectArr("Hello, I'm <%first%> <%last%>, and I <3 being a <%occupation%>. I am > blah") ); console.log( convertToObjectArr("Hello") ); console.log( convertToObjectArr("Hello, I'm <%first%>") );
这是我的方法。 如果您使用正则表达式,您可以简化很多(这基本上是正则表达式的确切用例)
target = "Hello, I'm <%first%> <%last%>, and I <3 being a <%occupation%>. I am > blah" const split = (el) => { const parts = el.split('%>') return [{type: 'token', value: parts[0]}, {type: 'string', value: parts[1]}] } const parts = target.split('<%').map(el => el.indexOf('%>') === -1? {type: "string", value: el}: split(el) ).flat() console.log(parts)
您可以使用词法分析器来标记您的字符串。 我在这个例子中使用了moo :
const lexer = moo.compile({ token: {match: /<%.+?%>/, value: raw => raw.slice(2, -2)}, strlt: /.+?(?=<%)/, strrt: /(?<=%>).+/ }); lexer.reset("Hello, I'm <%first%> <%last%>, and I <3 being a <%occupation%>. I am > blah"); console.log( [...lexer].map(({ type, value }) => ({ type: (type === 'token'? type: 'string'), value })) );
<script src="https://unpkg.com/moo@0.5.1/moo.js"></script>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.