简体   繁体   English

在字符串中获取 substring 之前和之后的所有内容

[英]In a string get everything before and after the substring

I'm working in angular trying to create a logic for Fill in the blanks where the user can input text in textarea and then make as many blanks as they want from a sentence.我在 angular 工作,试图创建一个填充空白的逻辑,用户可以在 textarea 中输入文本,然后从一个句子中创建尽可能多的空白。

For example: "This is a bowl of fruit"例如:“这是一碗水果”

If the user decides to make "bowl" as a blank they simply would put 2 brackets around it or click on a button and the above sentence would be changed to如果用户决定将“碗”设为空白,他们只需在其周围放置 2 个括号或单击一个按钮,上述句子将更改为

"This is a [[bowl]] of fruit." “这是[[碗]]水果。”

To do this I've the following code if the user decides to select the word and click on button to make the blank.要做到这一点,如果用户决定 select 这个词,我有以下代码并单击按钮使空白。

html.component 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>

component.ts组件.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"
   
  }

What I'm trying to achieve is to get data in the following format:我想要实现的是获取以下格式的数据:

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

The text before the blank and after the blank is type: Text.空格之前和空格之后的文本是类型:文本。 The text in the blank is type: "Word".空白处的文本是类型:“Word”。 I'm able to get the text before and after the blank as:我能够在空白之前和之后获取文本:

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

Issue问题

If I make another blank lets say from the sentence "This is a [[bowl]] of Fruit" I make "Fruit" as a blank too, This is a [[bowl]] of [[Fruit]].如果我再做一个空白,让我们从句子“This is a [[bowl]] of Fruit”中说,我也将“Fruit”设为空白,This is a [[bowl]] of [[Fruit]]。 Then how can I achieve the following array:那么我怎样才能实现以下数组:

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

You could use .matchAll() with a regular expression to match all occurrences of [[ and ]] .您可以将.matchAll()正则表达式一起使用来匹配所有出现的[[]] This is done using a regular expression, which also groups the text inside of the square brackets.这是使用正则表达式完成的,该表达式还将方括号内的文本分组。 The .matchAll() method gives back an iterator, which you can then turn into an array using the spread syntax ... . .matchAll()方法返回一个迭代器,然后您可以使用扩展语法将其转换为数组... The elements in the array contain the match and the group in the zero-th and first index of the array, which you can pull out using destructuring assignment .数组中的元素包含数组的第零个和第一个索引中的匹配项和组,您可以使用解构赋值将其拉出。 You can also pull out other properties such as the index at which the match occurred.您还可以提取其他属性,例如发生匹配的索引。 Using this, you can work out the text between each match, and then add that to your resulting array.使用它,您可以计算出每个匹配之间的文本,然后将其添加到结果数组中。 You can then perform a filter to remove any object that contains an empty from your result.然后,您可以执行过滤器以从结果中删除任何包含空的 object。 See example below:请参见下面的示例:

 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));

If you need to optimize this, you could be more considerate about what you return from the .flatMap() , that way, you won't need to perform a second iteration over your result to filter.如果您需要对此进行优化,您可以更加考虑从.flatMap()返回的内容,这样,您就不需要对结果执行第二次迭代来过滤。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM