Regex двойная проблема разделения пробелов - PullRequest
1 голос
/ 10 августа 2010

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

ABC  DE  FGHIJ   KLM    NO  P  QRST

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

Однако, для моей проблемы, только 1 пробел МОЖЕТвстречаются в слове, например

AB C  DE  FG HIJ   KLM    NO  P  QRST

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

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

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

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

Буду очень признателен за вашу помощь.Заранее спасибо.

Саад

Ответы [ 6 ]

3 голосов
/ 10 августа 2010

Самое простое решение - разделить на \s{2,}, чтобы получить «слова», которые вы хотите, но если вы настаиваете на поиске токенов, то где, как и раньше, у вас есть \S+, то у вас сейчас есть \S+(\s\S+)* , Это именно то, что написано: \S+, за которым следует ноль или более (\s\S+). Вы можете использовать группу без захвата для производительности, т.е. \S+(?:\s\S+)*. Вы можете даже сделать каждое повторение притяжательным, если ваш аромат поддерживает его для дополнительного усиления, то есть \S++(?:\s\S++)*+.

Вот фрагмент кода 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 голос
/ 10 августа 2010

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

\ s {2,}

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

$ list = preg_split ('/ \ s {2,} /', $ string);

1 голос
/ 10 августа 2010

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

\s{2,}
1 голос
/ 10 августа 2010

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

С уважением

rbo

0 голосов
/ 10 августа 2010

Если вы хотите сопоставить все слова (допуская один пробел в строке), попробуйте \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+)?.

0 голосов
/ 10 августа 2010

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

Редактировать: мне кажется, что любой используемый вами язык / инструментарий может не поддерживать "расщепление"строка, использующая регулярное выражение напрямую.В этом случае вы можете реализовать эту функцию, и вместо попытки сопоставить WORDS на входе, сопоставить SPACES и использовать информацию из этих совпадений (позиция,длина), чтобы извлечь слова между матчами.В некоторых языках (.NET, другие) эта функция встроена.

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