Разделите строку из числовых точек и сохраните только операторы точек в новом массиве

У меня есть этот ввод-

"\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?"

Я хочу этот вывод-

[
  "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?",
]

Я пробовал это-

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.info(result);

Объяснение кода-.

  1. Во-первых, я удалил все разрывы строк и некоторые ненужные строки.
  2. Во-вторых, я разделил строку из этого формата <integer><dot><space>, т.е. "1. ", "2. " и т.д.
  3. Наконец, отфильтрованы только числовые операторы точек в отдельном массиве.

Решение работает нормально, но я не уверен, что это правильный способ сделать это из-за этой жестко запрограммированной операции удаления - replace('Open Ended Questions:', '').replace('Closed Ended Questions:', '')

Может ли кто-нибудь предложить лучший/несложный/правильный способ сделать это?

Я бы сначала разделил на разрывы строк, а затем обработал бы каждый вопрос. То, как вы это делаете, может привести к ошибке, если один из этих вопросов содержит подстроку формы <integer><dot><space> (например, ссылка на предыдущий вопрос).

Fractalism 31.01.2023 13:03

Звучит достаточно хорошо, я не думаю, что вы все равно можете оптимизировать его с точки зрения производительности/удобочитаемости. Оставь как есть, отлично!

kissu 31.01.2023 13:17

Спасибо, @Fractalism. Ваша точка зрения верна, мое решение не сработает в этом случае подстроки.

Neha Soni 01.02.2023 06:05
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
3
3
117
6
Перейти к ответу Данный вопрос помечен как решенный

Ответы 6

  1. Разделить на строки
  2. Фильтровать строки
  3. Сопоставьте линии (удалив перечислитель)

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
  .filter((line) => /^\d+\./.test(line))
  .map((line) => line.replace(/^\d+\./, "").trim());

console.info(listItems);

Некоторые предложения: 1. (\d+) не нужны круглые скобки (хотя, если они там для удобочитаемости, тогда все в порядке) 2. . должен быть \., чтобы соответствовать буквальному символу точки 3. Символ пробела можно заменить на \s+, чтобы соответствовать нескольким последовательным пространства

Fractalism 31.01.2023 13:14
Ответ принят как подходящий

Перебрать строки из ввода и, если строка соответствует /^\d+\.\s+ (то есть цифрам-точкам-пробелам), поместить оставшуюся часть строки в массив:

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.info(output)

Вы также можете сделать это с помощью одного регулярного выражения, но это будет менее читаемо 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.info(output)
  1. Если вы разделите новую строку, вы получите

    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. Затем вы можете отфильтровать пустые и нерелевантные строки.

  3. Затем удалите цифры в начале.

Использование положительного просмотра назад (?<=) и просмотра вперед (?=):

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(/(?<=^\d+\. +).+?(?=\n|$)/gm)
console.info(items);

Пояснение к: Regex101.com

  • lookbehind: (?<=\n\d+\. +) Начало строки, одна или несколько цифр, точка, один или несколько пробелов
  • нежадное совпадение .+? любой символ один или несколько раз как можно меньше
  • просмотр вперед: (?=\n|$) новая строка или конец строки

Без ретроспективных утверждений

используйте это упрощенное регулярное выражение, которое в основном соответствует началу строки ^, имеющему цифру / с, за которыми следует шаблон точки и пробела, и захватывает оставшуюся строку (.+) до конца строки $ (с глобальными и многострочными флагами gm)

/^\d\. (.+)$/gm

Демонстрация Regex101.com и объяснение

Для поддержки браузеров на основе WebKit, таких как Safari, которые не поддерживают утверждение Lookbehind, вы можете использовать String.prototype.matchAll() , чтобы получить итератор с совпавшими группами. Используйте синтаксис распространения ..., чтобы получить 2D-массив и получить доступ к первой соответствующей группе, используя match[1], и преобразовать его в массив, используя Array.ptototype.map()

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.matchAll(/^\d\. (.+)$/gm)].map(m => m[1]);
console.info(items);

Для дополнительной поддержки старых браузеров Internet Explorer, которые не поддерживают метод String.prototype.matchAll(), используйте .exec(), например:

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 reg = /^\d\. (.+)$/gm;
const res = [];
let m;
while(m = reg.exec(str)) res.push(m[1]);
console.info(res);

Спасибо, @Roko, это самое простое решение. Единственная проблема в том, что я прочитал об этих операторах и обнаружил, что оператор lookbehind не поддерживается в браузерах, отличных от V8, таких как Safari и Internet Explorer, и этот ответ также не работает в Safari. У вас есть какие-нибудь мысли по этому поводу?

Neha Soni 01.02.2023 06:40

Это зависит от вашего ввода, и всегда ли вопрос имеет одинаковую структуру? Если да, вам нужно определить регулярное выражение, соответствующее формату ваших вопросов, и оттуда вам не нужно ничего заменять предложениями с пустыми строками:

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.info(result);

Я предполагаю, что каждый вопрос заканчивается на ? и начинается с новой строки \n в соответствии с указанной вами входной строкой. Принимая во внимание приведенный выше шаблон, вот обходное решение для достижения требуемого результата.

// Input string
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?";

// Splitted the input string based on the new line character '\n'
const splittedStr = str.split("\n");

// Filtered out the array items which ends with question mark (?)
const questionsArr = splittedStr.filter(str => str.endsWith('?'));

// Finally removing the numbers from the starting of the question texts.
const res = questionsArr.map(str => str.replace(/^[\d]+\.\ /, ''));

// Desired output
console.info(res);

Другие вопросы по теме