2016-11-14 2 views
1

Предположим, у меня есть строка вроде этого: abc def ghi jkl (Я просто поставил пространство в конце для простоты, но для меня это не имеет особого значения), и я хочу захватить его «куски» "следующим образом:Tokenizing строка с регулярным выражением

abc 

def 

ghi 

jkl 

если и только если в строке есть 1-4" куска ". Я уже пробовал следующее регулярное выражение:

^([^ ]+){1,4}$ 

на Regex101.com, но он только фиксирует последнее появление. Выдается предупреждение об этом:

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

Как исправить регулярное выражение для достижения моей цели?

+1

Это 1 или более символов является проблемой XY. Разделите/взорвите строку с пробелом и проверьте, содержит ли результирующий массив 4 непустых элемента.Тем не менее, можно проверить и * сопоставить множественные последующие вхождения * (не захватывать) с помощью PCRE, а не POSIX. –

+0

Итак, я могу сделать это «вручную», используя только язык программирования, а не регулярные выражения, но есть ли более автоматическое решение? На самом деле он должен быть частью более сложного выражения. PCRE подходит для меня. – mzzz

+0

Если ваш исполняемый файл разрешает доступ к значениям группы захвата, нет решения, которое будет работать для вас. –

ответ

0

Поскольку у вас нет доступа к коду, единственным решением, которое вы можете использовать, является регулярное выражение, основанное на операторе \G, которое будет допускать только последовательные совпадения и привязку в начале, которые потребуют от 1 до 4 не-белых фрагментов в строке.

(?:^(?=\s*\S+(?:\s+\S+){0,3}\s*$)|\G(?!^))\s*\K\S+ 

Смотрите regex demo

Детали:

  • (?:^(?=\s*\S+(?:\s+\S+){0,3}\s*$)|\G(?!^)) - пользовательские границы, которая проверяет, если:

    • ^(?=\s*\S+(?:\s+\S+){0,3}\s*$) - строка стартовую позицию (^) т шлем следует с 1 до 4 непробельных куски, разделенные пробелами 1+, и замыкающая/ведущие пробелы разрешены, слишком
    • | - или
    • \G(?!^) - текущее положение в конце предыдущего успешного матча (\G также соответствует началу строки, таким образом, мы должны использовать отрицательный предпросмотр, чтобы исключить эту позицию соответствия, так как есть отдельная проверка выполняется)
  • \s* - ноль или более пробельные символы

  • \K - оператор сброса матч отбрасывая весь текст согласованного до сих пор
  • \S+ - другие, чем пробельные
+1

Добро пожаловать; принято. – mzzz

+0

Есть проблема с выражением. Он отлично работает в regex101.com, но используется внутри кода C++ (с использованием «простого» интерфейса C) соответствует только токен-фик, т.е. функция pcre_exec() возвращает 1. Например, для «abc def ghi» это вернется только «abc». Любая помощь? – mzzz

+0

Это не связано с моим ответом, но вы можете взглянуть на [этот поток SO] (http://stackoverflow.com/a/1421923/3832970), я думаю, вы найдете решение своей новой проблемы. –

0

Это может быть сделано на Linux с помощью тр:

tr -sc 'a-zA-Z' '\n' <text.txt> out_text.txt 

где в файле text.txt ваша строка будет нормализована.

+0

Выражение встроено в обычный исполняемый файл, поэтому я не хотел бы этого делать. – mzzz

Смежные вопросы