首页 > 解决方案 > 在字符串中获取子字符串之前和之后的所有内容

问题描述

我正在尝试创建一个用于填充空白的逻辑,用户可以在文本区域中输入文本,然后从一个句子中制作尽可能多的空白。

例如:“这是一碗水果”

如果用户决定将“碗”设为空白,他们只需在其周围放置 2 个括号或单击一个按钮,上述句子将更改为

“这是[[碗]]水果。”

为此,如果用户决定选择单词并单击按钮使空白成为空白,我将使用以下代码。

html.component

   <textarea (ngModel)]="blankText" #blankArea rows="4" cols="50"></textarea>
   <button class="btn btn-link" (click)="makeBlank(blankArea.selectionStart, blankArea.selectionEnd)">Make Blank</button>

组件.ts

  makeBlank(start, end) {
    this.blankStatement = [];
    let result;
    let sentence = this.blankText;
    let blankStart = '[[';
    let blankEnd = ']]';

    result = sentence.slice(0, start) + blankStart + sentence.slice(start);
    end = end + 2;
    result = result.slice(0, end) + blankEnd + result.slice(end);
    this.blankText = result;

    //Get Blank Data
    var part = result.substring(
      result.lastIndexOf('[[') + 2,
      result.lastIndexOf(']]')
    );
    let obj = {
      blank: part,
    };
    this.blanks.push(obj); //This saves the blank word i.e "Bowl"
   
  }

我想要实现的是获取以下格式的数据:

blankStatement = 
[ 
{type: "Text", text: "This is a"}, 
{type: "Word", blank:"bowl"}, 
{type:"Text", text:"of fruit"}
]

空格之前和空格之后的文本是类型:文本。空白处的文本是类型:“Word”。我能够在空白之前和之后获取文本:

let preText = this.blankText.substring(0, preText.indexOf('['));
let postText = this.blankText.split(']').pop();

问题

如果我再做一个空白,让我们从句子“This is a [[bowl]] of Fruit”中说,我也将“Fruit”设为空白,This is a [[bowl]] of [[Fruit]]。那么我怎样才能实现以下数组:

 blankStatement = 
[ 
{type: "Text", text: "This is a"}, 
{type: "Word", blank:"bowl"}, 
{type: "Text", text:"of"},
{type: "Word", blank:"fruit" }
]

标签: javascriptarraysstringecmascript-6logic

解决方案


您可以使用.matchAll()with正则表达式来匹配所有出现的[[and ]]。这是使用正则表达式完成的,该表达式还将方括号内的文本分组。该方法返回一个迭代器,然后您可以使用扩展语法.matchAll()将其转换为数组。数组中的元素包含数组的第零和第一个索引中的匹配项和组,您可以使用解构赋值将其拉出 .... 您还可以提取其他属性,例如发生匹配的索引。使用它,您可以计算出每个匹配之间的文本,然后将其添加到结果数组中。然后,您可以执行过滤器以从结果中删除任何包含空的对象。请参见下面的示例:

const str = "This is a [[bowl]] of [[Fruit]]";

const getWordsAndText = (str) => {
  const matches = [...str.matchAll(/\[\[([^\]\]]+)\]\]/g)];
  let lastIndex = 0;
  return matches.flatMap(({0: match, 1: blank, index, input}) => {
    const arr = [
      {type: "Text", text: input.substring(lastIndex, index).trim()},
      {type: "Word", blank: blank.toLowerCase()}
    ];
    lastIndex = index + match.length;
    return arr;
  }).concat({type: "Text", text: str.substring(lastIndex).trim()}).filter(({text}) => text !== "");
}

console.log(getWordsAndText(str));

如果您需要对此进行优化,您可以更加考虑从 中返回的内容.flatMap(),这样,您就不需要对结果执行第二次迭代来过滤。


推荐阅读