Home > OS >  Split a string from numeric points and keep only the points' statements in a new array
Split a string from numeric points and keep only the points' statements in a new array

Time:01-31

I have this input-

"\n\nOpen Ended Questions:\n1. What makes Vue a popular choice for web development?\n2. How does Vue compare to other JavaScript frameworks?\n3. What are the advantages of using Vue?\n\nClosed Ended Questions:\n1. Does Vue support server-side rendering?\n2. Is Vue compatible with TypeScript?\n3. Does Vue have a built-in router?"

I want this output-

[
  "What makes Vue a popular choice for web development?",
  "How does Vue compare to other JavaScript frameworks?",
  "What are the advantages of using Vue?",
  "Does Vue support server-side rendering?",
  "Is Vue compatible with TypeScript?",
  "Does Vue have a built-in router?",
]

I tried this-

let string = "\n\nOpen Ended Questions:\n1. What makes Vue a popular choice for web development?\n2. How does Vue compare to other JavaScript frameworks?\n3. What are the advantages of using Vue?\n\nClosed Ended Questions:\n1. Does Vue support server-side rendering?\n2. Is Vue compatible with TypeScript?\n3. Does Vue have a built-in router?"

// First, remove all line breaks and two strings
string = string.replace(/(\r\n|\n|\r)/gm, "").replace('Open Ended Questions:', '').replace('Closed Ended Questions:', '');

// Split the string from this format, "<integer><dot><space>"
let result = string.split(/(\d )\.\ /);

// Filter the only items which are not empty and not a number
result = result.filter(item => item && isNaN(item));

// Final result
console.log(result);

Code explanation-.

  1. Firstly, I removed all line breaks and some non-required strings.
  2. Secondly, I split the string from this format <integer><dot><space>, i.e. "1. ", "2. ", etc.
  3. At last, filtered only the numeric points' statements in a separate array.

The solution is working fine but I am not sure if its the right way to do this, because of this hardcoded removal operation- replace('Open Ended Questions:', '').replace('Closed Ended Questions:', '')

Can anyone please suggest a better/non-complex/correct way to do this?

CodePudding user response:

  1. Split into lines
  2. Filter the lines (only keeping the lines that start with a number and followed by a dot)
  3. Map the lines (removing the enumerator)
const input = "\n\nOpen Ended Questions:\n1. What makes Vue a popular choice for web development?\n2. How does Vue compare to other JavaScript frameworks?\n3. What are the advantages of using Vue?\n\nClosed Ended Questions:\n1. Does Vue support server-side rendering?\n2. Is Vue compatible with TypeScript?\n3. Does Vue have a built-in router?"

const lines = input.split('\n');
const listItems = lines afterwards
  .filter((line) => /^(\d )./.test(line))
  .map((line) => line.replace(/^(\d ). /, "");

CodePudding user response:

Iterate the lines from the input and if a line matches /^\d \.\s (that is, digits-dot-spaces), put the rest of the line in the array:

input = "\n\nOpen Ended Questions:\n1. What makes Vue a popular choice for web development?\n2. How does Vue compare to other JavaScript frameworks?\n3. What are the advantages of using Vue?\n\nClosed Ended Questions:\n1. Does Vue support server-side rendering?\n2. Is Vue compatible with TypeScript?\n3. Does Vue have a built-in router?"

output = []

for (let line of input.split('\n')) {
  line = line.trim()
  let m = line.match(/^\d \.\s (. )/)
  if (m)
    output.push(m[1])
}

console.log(output)

You can also do that with one single regular expression, but this would be less readable IMO:

input = "\n\nOpen Ended Questions:\n1. What makes Vue a popular choice for web development?\n2. How does Vue compare to other JavaScript frameworks?\n3. What are the advantages of using Vue?\n\nClosed Ended Questions:\n1. Does Vue support server-side rendering?\n2. Is Vue compatible with TypeScript?\n3. Does Vue have a built-in router?"

output = [...input.matchAll(/^\d \.\s (. )/gm)].map(r => r[1])

console.log(output)

CodePudding user response:

Using positive lookbehind (?<=) and lookahead (?=):

const str = "\n\nOpen Ended Questions:\n1. What makes Vue a popular choice for web development?\n2. How does Vue compare to other JavaScript frameworks?\n3. What are the advantages of using Vue?\n\nClosed Ended Questions:\n1. Does Vue support server-side rendering?\n2. Is Vue compatible with TypeScript?\n3. Does Vue have a built-in router?";

const items = str.match(/(?<=\n\d \. ). ?(?=\n|$)/gm)
console.log(items);

Explanation on: Regex101.com

  • lookbehind: (?<=\n\d \. ) newline, one or more digits , dot, one or more spaces
  • non-greedy match . ? any character one or more times as few as possible
  • until lookahead: (?=\n|$) newline or end of string

CodePudding user response:

  1. In case you split with new line you will get

    part  0: 
    part  1: 
    part  2: Open Ended Questions:
    part  3: 1. What makes Vue a popular choice for web development? 
    part  4: 2. How does Vue compare to other JavaScript frameworks?
    part  5: 3. What are the advantages of using Vue?
    part  6: 
    part  7: Closed Ended Questions:
    part  8: 1. Does Vue support server-side rendering?
    part  9: 2. Is Vue compatible with TypeScript?
    part 10: 3. Does Vue have a built-in router?
    
  2. Then you can filter empty and irrelevant rows.

  3. Then remove numbers at the beginning.

CodePudding user response:

It depends on your input and if the question have always the same structure? If yes you have to define a regex that matches your questions format and from there you don't need to replace anything the sentences with empty strings:

let string = "\n\nOpen Ended Questions:\n1. What makes Vue a popular choice for web development?\n2. How does Vue compare to other JavaScript frameworks?\n3. What are the advantages of using Vue?\n\nClosed Ended Questions:\n1. Does Vue support server-side rendering?\n2. Is Vue compatible with TypeScript?\n3. Does Vue have a built-in router?"
// ([0-9])  is the question number and it has to be 1 or more than one character
// \. is the dot after question number
// .  is your question
// (\?)? the first question mark after the question text
let regexp = /([0-9]) \.. (\?)?/g;
var questions = string.match(regexp);
var result = [];
questions.forEach((l) => result.push(l.replace(/([0-9]) \./g,'').trim()));
console.log(result);

  • Related