Проблема двойного пробела в регулярном выражении regex

Вопрос:Я хочу, чтобы регулярное выражение соответствовало словам, которые ограничены двумя или более символами пробела, например ABC DE FGHIJ KLM NO P QRST Обратите внимание на двойное или большее количество пробелов между алфавитами. Написание регулярного выражения для такой задачи легко, так как мне нужны только первые 4 слова, так как мы можем искать слово, используя S+

Вопрос:

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

ABC DE FGHIJ KLM NO P QRST

Обратите внимание на двойное или большее количество пробелов между алфавитами. Написание регулярного выражения для такой задачи легко, так как мне нужны только первые 4 слова, так как мы можем искать слово, используя S+ или S+?

Однако для моей проблемы в слове может встречаться только 1 пробел CAN, например

AB C DE FG HIJ KLM NO P QRST

Здесь AB C – это слово, а FG HIJ – также слово. Короче говоря, мы хотим изолировать символы, которые прокручиваются двойным или большим количеством пробелов, я пытался использовать это регулярное выражение,

.+? +.+? +.+? +.+? +

он соответствует очень быстро, но для строк он не слишком много времени. (Здесь приведены 4 матча, на практике мне нужно больше соответствовать).

Я нуждаюсь в лучшем регулярном выражении, чтобы выполнить это, чтобы можно было избежать всего обратного отслеживания. [^ ]* – это регулярное выражение, которое будет соответствовать увеличению пробела. Не можем ли мы указать отрицательный набор символов, где мы продолжим сопоставление в случае одного пробела и разрыва при возникновении 2? Я пробовал использовать позитивный взгляд, но неудачно провалился.

Я очень благодарен за вашу помощь. Спасибо заранее.

Саад

Лучший ответ:

Самое простое решение – разделить на s{2,}, чтобы получить “слова”, которые вы хотите, но если вы настаиваете на сканировании токенов, тогда, когда у вас есть S+, теперь у вас есть S+(sS+)*, Именно это говорит: S+, за которым следует ноль или более (sS+). Вы можете использовать группу без захвата для производительности, т.е. S+(?:sS+)*. Вы можете даже сделать каждое повторное притяжательное, если ваш вкус поддерживает его для дополнительного повышения, т.е. S++(?:sS++)*+.

Здесь приведен фрагмент Java для демонстрации:

String text = «AB C DE FG HIJ KLM NO P QRST»; Matcher m = Pattern.compile(«\S++(?:\s\S++)*+»).matcher(text); while (m.find()) { System.out.println(«[» + m.group() + «]»); }

Отпечатки:

[AB C] [DE] [FG HIJ] [KLM] [NO] [P] [QRST]

Вы можете, конечно, заменить только символ пробела вместо s, если это ваше требование.

Ссылки

Ответ №1

если вы знаете, что такое разделитель ( ss +), вы можете разделить вместо match.
Просто разделите на два или более пробела.

Привет

БВУ

Ответ №2

Как использовать этот шаблон:

s{2,} Ответ №3

Я думаю, что еще проще сопоставить 2 или более пробелов:

с {2}

В PHP раскол будет выглядеть следующим образом

$list = preg_split (‘/ s {2,}/’, $string);

Ответ №4

Почему не что-то вроде ss + (один пробельный символ, затем один или несколько пробельных символов)?

Изменить: мне кажется, что любой язык/инструментарий, который вы используете, может не поддерживать “разделение” строки с использованием регулярного выражения напрямую. В этом случае вы можете реализовать эту функциональность и вместо того, чтобы пытаться сопоставить СЛОВА во входном файле, соответствовать SPACES и использовать информацию из этих совпадений (позиция, длина) для извлечения слов между совпадениями. На некоторых языках (.NET, другие) эта функциональность встроена.

Ответ №5

Если вы хотите совместить все слова (допускающие одно место в строке), попробуйте S+(?:[ ]S+)* (класс символов не нужен и может быть просто символом пробела, но я включил его для ясности). Он указывает, что требуется хотя бы один символ без пробелов, а пробелу не может следовать другой.

Вы не указали, какой язык вы используете, но вот пример в PHP:

$string = «AB C DE FG HIJ KLM NO P QRST»; $matches = array(); preg_match_all(‘/S+(?:[ ]S+)*/’, $string, $matches); // $matches will contain ‘AB C’, ‘DE’, ‘FG HIJ’, ‘KLM’, ‘NO’, ‘P’, ‘QRST’

Если требования не более одного места на слово, просто измените * в конце на ?: S+(?:[ ]S+)?.

Оцените статью
Добавить комментарий