Вопрос:
Я хочу, чтобы регулярное выражение соответствовало словам, которые ограничены двумя или более символами пробела, например
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+)?.