Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Замена повторяющихся подстрок из подчеркиваний разной длины в строке. (https://javascript.ru/forum/misc/80466-zamena-povtoryayushhikhsya-podstrok-iz-podcherkivanijj-raznojj-dliny-v-stroke.html)

savsoft 07.06.2020 23:12

Замена повторяющихся подстрок из подчеркиваний разной длины в строке.
 
Всем привет, у меня возникла проблема.

Есть задача, в одном предложении (строке), есть пропущенные слова, которые отображаются, как несколько подчеркиваний _______ . Их нужно заменить на одинаковый шорткод (к примеру на [shortcode]).

Для варианта с одним пропущенным словом я ищу последовательность пробел и два подчеркивания ' __' - это начало подстроки, и два подчеркивания и пробел '__ ' - это конец подстроки. И ее соответственно заменяю.

Но теперь пропущенных слов может быть несколько, подстроки из подчеркиваний могут быть разной длины, да и после подчеркиваний может не быть пробела, если это конец предложения. Просто копировать строку по одному символу и проверять на подчеркивание? Или есть какой более умный способ?

Спасибо

laimas 07.06.2020 23:18

Цитата:

Сообщение от savsoft
И ее соответственно заменяю

Её, это что из - начало подстроки, конец подстроки или то что между ними?

savsoft 07.06.2020 23:43

Цитата:

Сообщение от laimas (Сообщение 525552)
Её, это что из - начало подстроки, конец подстроки или то что между ними?

Пока сделал так

var str = '____ you wanted to know ___________________ giving a good advice and getting him to return the ___.';
		var start = -1;
		var newstr = '';
		
		for (let i = 0; i < str.length; i++) {
		
			if (str[i] == '_' && start == -1) {
				start = i;
			}
			
			if (str[i] != '_' && start == -1) {
				newstr = newstr + str[i];
			}	
			
			if (str[i] != '_' && start != -1) {
				newstr = newstr + '[space]' + str[i];
				start = -1;
			}	
					
			
		}


Получаю

[space] you wanted to know [space] giving a good advice and getting him to return the [space].

laimas 08.06.2020 00:00

То есть нужно просто заменить все подчеркивания? А зачем рассказ о начале, конце?

str = str.replace(/_+/g, () => '[space]')

savsoft 08.06.2020 00:23

Цитата:

Сообщение от laimas (Сообщение 525552)
Её, это что из - начало подстроки, конец подстроки или то что между ними?

Цитата:

Сообщение от laimas (Сообщение 525556)
То есть нужно просто заменить все подчеркивания? А зачем рассказ о начале, конце?

str = str.replace(/_+/g, () => '[space]')

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

Спасибо

А можно как-то таким способом сразу поставить перед и после [space] по пробелу, если их нет. Если [space] в самом начале предложения, то пробел в начале не ставить и если в конце, то не ставить пробел перед точкой (восклицательным знаком и вопросом).

И что посоветуете почитать/посмотреть по регулярным выражениям.

Еще раз спасибо.

laimas 08.06.2020 00:38

Цитата:

Сообщение от savsoft
А можно как-то таким способом сразу поставить перед и после [space] по пробелу, если их нет

А в конечном итоге это для чего? Если это будет на странице (html), то в ней лишние пробелы не отображаются, так что можно и без проверок заменять на ' [space] '. Или не желательно такое?

https://developer.mozilla.org/ru/doc...Objects/RegExp

А уроков по нему в сети полно.

savsoft 08.06.2020 00:46

Цитата:

Сообщение от laimas (Сообщение 525562)
А в конечном итоге это для чего? Если это будет на странице (html), то в ней лишние пробелы не отображаются, так что можно и без проверок заменять на ' [space] '. Или не желательно такое?

https://developer.mozilla.org/ru/doc...Objects/RegExp

А уроков по нему в сети полно.

Есть много текстовых файлов с тестами для изучения английского. Теперь их переносят на сайт. Тексты проверяют и копируют целыми тестами. Иногда попадаются ошибки, а хотелось бы красивые предложения, чтобы не попадалось know[space]giving, а только know [space] giving

laimas 08.06.2020 01:24

Можно захватывать с краев любое количество пробелов (если они будут), а в конце еще и символы ".,?!", то есть знаки препинания любые возможные, а в функции проверять если ли такие в найденном, если есть, значит возвращать этот знак, иначе пробел. А вначале ставить пробел если это не первое найденное (по позиции).

var str = '____         you wanted to know,___________________    giving a good advice______, and getting him to return the ___.';

str = str.replace(/\s*_+\s*[\.\?!,]?/g, (v, i) => (i ? ' ' : '') + '[space]' + ((v = v.match(/[\.\?!,]{1}/)) ? v : ' '))

console.log(str)


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

laimas 08.06.2020 01:36

Можно поступить и иначе - разбить строку на массив по шаблону _+, соединив затем его в строку через " [space] ", а с краев строки соответственно добавить с пробелом только в конце и только в начале. Элементы массива перед соединением обойти функцией map, удалив в них крайние пробелы (либо сразу разбивать с учетом пробелов и исключить map).

savsoft 08.06.2020 10:41

Цитата:

Сообщение от laimas (Сообщение 525565)
Можно поступить и иначе - разбить строку на массив по шаблону _+, соединив затем его в строку через " [space] ", а с краев строки соответственно добавить с пробелом только в конце и только в начале. Элементы массива перед соединением обойти функцией map, удалив в них крайние пробелы (либо сразу разбивать с учетом пробелов и исключить map).

Спасибо, буду разбираться.


Часовой пояс GMT +3, время: 07:05.