【问题标题】:In a string get everything before and after the substring在字符串中获取子字符串之前和之后的所有内容
【发布时间】:2021-04-05 04:20:40
【问题描述】:

我正在 Angular 中工作,试图创建一个填充空白的逻辑,用户可以在 textarea 中输入文本,然后从一个句子中创建尽可能多的空白。

例如: “这是一碗水果”

如果用户决定将“碗”设为空白,他们只需在其周围放置 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"}
]

空格前后的文字是type:Text。空白处的文本是类型:“Word”。 我能够将空白前后的文本设为:

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

问题

如果我再做一个空白,让我们从句子“这是 [[bowl]] of Fruit”中说,我也将“Fruit”作为空白,这是 [[Fruit]] 的 [[bowl]]。 那我怎样才能实现如下数组:

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

【问题讨论】:

  • 我在我的一个项目中做过这个 - 所以把它当作一个建议 - blankStatement = { text: "This is a [[bowl]] of [[Fruit]]" 空白: [ {wordIndex: 3, blank:"bowl"}, {wordIndex: 5, blank:"fruit" } ] } 因此,如果您跟踪单词索引,它将帮助您解析和添加空白。

标签: javascript arrays string ecmascript-6 logic


【解决方案1】:

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

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() 返回的内容,这样您就无需对结果进行第二次迭代以进行过滤。

【讨论】:

  • 这是一个非常简洁的解决方案,虽然唯一的是,我确实得到了空白之前的文本和空白本身,但没有得到空白之后的句子。您能否添加一些方法来获取空白后的部分,以便我可以将其标记为已接受的答案。
  • @StringName 抱歉,我忘了在结果中添加任何剩余的文本。我在结果中添加了一个.concat() 方法,如果需要,它将添加任何剩余的文本
猜你喜欢
  • 1970-01-01
  • 2017-09-12
  • 2010-12-23
  • 2018-08-08
  • 1970-01-01
  • 1970-01-01
  • 2015-06-06
  • 2022-11-10
  • 1970-01-01
相关资源
最近更新 更多