Как разделить предложение на слова и знаки препинания?

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

Я попытался добиться этого, разбив исходный текст на массив, состоящий из каждого слова в другом индексе массива. (используя .split(" ")) Когда найдено несколько слов, удовлетворяющих условию, и заменено, я теряю знаки препинания, которые иногда следуют за ними. Мой язык чрезвычайно абстрактный, потому что по сути я хочу разделить строку на слова и знаки препинания, но знаки препинания должны быть отдельным объектом в массиве, только если за знаками препинания следует пробел. еще не научился писать вопросы)

Поясним на примере:

Предложение «Мой код не работает, и я не знаю, как его получить». следует разделить на ["My","code","doesn't","work","and",",","I","don't","know","how","to","get","it","to","."]

Пожалуйста, опубликуйте пример входных данных и ожидаемого результата, а также свой набор возможностей.

FiddlingAway 08.06.2024 16:51

Это называется «лексическим анализом» или «токенизацией»; он же «забава со струнами», он же «смерть от ASCII». На высоком уровне, таком как ваш пример, регулярное выражение отлично, но на более низком уровне оно выполняется по одному символу за раз. Всегда любил это, лишь иногда ненавидел.

l3l_aze 08.06.2024 19:53

@ih8bugs ... Вы можете взглянуть на предоставленный позже ответ, в котором используется специализированный стандартный API JS для обработки сегментации/токенизации текста на конкретном языке.

Peter Seliger 09.06.2024 01:47
Поведение ключевого слова "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) для оценки ваших знаний,...
1
3
81
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Вы можете использовать регулярное выражение, которое соответствует пробелам и знакам препинания, чтобы разделить строку, используя хитрость использования группы захвата, чтобы вы могли проверить, была ли строка чистыми пробелами или нет, и если да, сохранить ее в массиве.

function splitIntoWords(s) {
  return s.split(/([\s,.])/).filter((a) => a.trim());
}
> splitIntoWords("My code doesn't work and, I don't know how to get it to.")
(15) ['My', 'code', "doesn't", 'work', 'and', ',', 'I', "don't", 'know', 'how', 'to', 'get', 'it', 'to', '.']

(Если вам по какой-то причине нужно вклеить одиночный . обратно в предыдущее слово, как в вашем примере, вы можете сделать это в качестве следующего шага.)

Точка после двух была опечаткой, извините.

ih8bugs 08.06.2024 16:56

Это не работает для таких знаков препинания, как «!» и "?" но это можно исправить, добавив эти знаки препинания в конец квадратных скобок в аргументе начального метода разделения.

ih8bugs 08.06.2024 17:11

Ага. Я не хотел предполагать. (Квадратные скобки обозначают класс символов, где специальная последовательность \s — это «любой пробел», а остальные символы — это просто символы (кроме таких диапазонов, как a-z).)

AKX 08.06.2024 17:20
Ответ принят как подходящий

API интернационализации JavaScript имеет функцию Intl.Segmenter именно для таких задач, поскольку из-за сложности языка решение, основанное исключительно на регулярных выражениях и охватывающее все аспекты языка и специфику локалей, может оказаться затруднительным в использовании.

Его использование применительно к проблеме ОП может выглядеть аналогично следующему примеру кода...

const sampleText =
  "My code doesn't work and, I don't know how to get it to.";

const segmenter =
  new Intl.Segmenter('en', { granularity: 'word' });

const segmentList = [...segmenter.segment(sampleText)];

const finalResult = segmentList
  .filter(({ segment }) => !!segment.trim())
  .map(({ segment }) => segment)

console.info({ sampleText, finalResult, segmentList });
.as-console-wrapper { min-height: 100%!important; top: 0; }

Я понял, что когда я добавляю пробел и другие слова, между словом и следующим за ним знаком препинания тоже остается пробел. Я попытался исправить это, добавив оператор if, который добавляет после слова только пробел, а не знаки препинания, глядя на длину строки, но это добавляет много других сложностей, и мой код выглядит так, будто он использует обходной метод. чтобы выполнить что-то простое, поэтому я откажусь от этого пути и создам отдельный вопрос, который напрямую делает то, что я хочу.

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