2014-01-25 6 views
2

Я пытаюсь заменить все слова, кроме первых трех слов из строки (с помощью текстовой панели).Регулярное извлечение первых 3 слов из строки

значение Ex: This is the string for testing.

Я хочу, чтобы извлечь только 3 слова: This is the из выше строки и удалить все остальные слова.

Я вычислил регулярное выражение в соответствии с тремя словами (\w+\s+){3}, но мне нужно совместить все остальные слова, кроме первых 3 слов, и удалить другие слова. Может кто-нибудь мне помочь?

+1

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

+0

Это своего рода совместная работа, но, похоже, она работает на http://www.phpliveregex.com/p/3jo. '^ ((\ W + \ S +) {3}) (. *) $'. С этим вы получаете ... все, первые 3, 3, а затем остальные ... Не знаете, как вы могли бы использовать его оттуда. Не знаю, как это работает для Textpad, поскольку я понятия не имею, что это такое. – qooplmao

+0

@Wrikken - плакат с текстовой панелью. Textpad утверждает: «Его мощный механизм регулярных выражений совместим с Perl и JavaScript». – bluefeet

ответ

5

как именно зависит от вкуса , но устранить все, кроме первых трех слов, вы можете использовать:

^((?:\S+\s+){2}\S+).* 

который захватывает первые три слова в capturin g group 1, а также остальную часть строки. Для вашей строки замены вы используете ссылку на группу захвата 1.В C# это может выглядеть следующим образом:

resultString = Regex.Replace(subjectString, @"^((?:\S+\s+){2}\S+).*", "${1}", RegexOptions.Multiline); 
1

EDIT: добавлен привязку начала строки к каждому регулярному выражению и добавлены специальные флаги TextPad.

Если вы хотите устранить первые три слова, и захватить остальные,

^(?:\w+\s+){3}([^\n\r]+)$ 

?: изменяет первые три слова в не захватывая группы, и захватывает все после него.

Это вы что искали? Я не совсем понимаю ваш вопрос или вашу цель.

Как было предложено, вот как раз наоборот. Захват первые три слова только, а остальное отбрасывают:

^(\w+\s+){3}(?:[^\n\r]+)$ 

Просто переместите: от первой ко второй группировке.

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

^(\w+)\s+(\w+)\s+(\w+)\s+(?:[^\n\r]+)$ 

А потом, к примеру, вы могли бы заменить друг с первой заглавной буквой:

Заменить: \u$1 \u$2 \u$3

This Is The

В TextPad в нижнем регистре \u в замене означает изменение только следующей буквы. Верхний регистр \U изменяет все после него (до следующего знака капитализации).

Попробуйте:

http://fiddle.re/f3hgv

(нажмите на [Java] или любой другой язык является наиболее уместным отметить, что \ и не поддерживается RegexPlanet.).

+0

Я думаю, что он пытается удалить все слова, кроме первого. 3. Может быть, дать ему 2 решения, где второе решение для этого случая. – alvits

+0

Хорошо. Ответ обновлен. – aliteralmind

0

Исходя из дубликата вопроса, то я выложу решение, которое работает для «традиционных» реализаций регулярных выражений, которые не поддерживают расширения Perl \s, \W и т.д. новоприбывших, которые являются не знакомы даже с тем, что существуют разные диалекты (ака вкусы) регулярных выражений, рекомендуется читать, например, Why are there so many different regular expression dialects?

Если у вас есть поддержка класса POSIX, вы можете использовать [[:alpha:]] для \w, [^[:alpha:]] для \W, [[:space:]] для \s и т.д. Но если мы предположим, что пробельные всегда будет пространство, и вы хотите, чтобы извлечь первые три жетона между вам это действительно не нужно.

[^ ]+[ ]+[^ ]+[ ]+[^ ]+ 

соответствует трем жетонам, разделенным пробегами пробелов. (Я помещаю пробелы в квадратные скобки, чтобы они выделялись, и их легко расширить, если вы хотите включить другие символы, а не только одно регулярное пространство ASCII в наборе разделителей маркеров. Например, если ваш диалект regex принимает \t для вкладки или вы можете вставить вкладку регулярной на своем месте, вы можете расширить это

[^ \t]+[ \t]+[^ \t]+[ \t]+[^ \t]+ 

в большинстве оболочек вы можете ввести вкладку буквальной с Ctrl + обвкладки, т.е. префикс его с код выхода, который часто набирается путем удержания клавиши ctrl и ввода v.)

Чтобы реально использовать это, вы можете захотеть сделать

grep -Eo '[^ ]+[ ]+[^ ]+[ ]+[^ ]+' file 

где одиночные кавычки необходимы для защиты регулярных выражений из оболочки (двойные кавычки будут работать здесь, тоже, но слабее, или backslashing каждый символ в регулярном выражении, которое имеет значение для оболочки, как метасимвол) или, возможно,

sed -r 's/([^ ]+[ ]+[^ ]+[ ]+[^ ]+).*/\1/' file 

заменить каждую строку только с захваченным выражением (в скобках сделать захват группу, которую вы можете сослаться назад с \1 на заменяемой части в s в пункте sed). Опция -r выбирает немного более функциональный диалект регулярного выражения, чем традиционные голые кости sed; если у вашего sed его нет, попробуйте -E или положите обратную косую черту перед каждой скобкой и знаком плюс.

Из-за того, что работают регулярные выражения, три простых метода легки, потому что механизм регулярного выражения всегда возвращает первое возможное совпадение на линии. Если вы хотите, чтобы три токена, начиная с секунд,, вы должны ввести выражение пропуска. Адаптирование sed сценария выше, что бы

sed -r 's/[^ ]+[ ]+([^ ]+[ ]+[^ ]+[ ]+[^ ]+).*/\1/' 

, где вы увидите, как я ставлю в знаке + без маркеров группы до захвата. (Это невозможно сделать с grep -o, если у вас нет grep -P, и в этом случае полная гамма расширений Perl доступна вам в любом случае.)

Если ваш диалект регулярного выражения поддерживает {m, n} повторение, вы можете, конечно, реорганизовать регулярное выражение, чтобы использовать это. Если вам нужно большое количество повторений, это, безусловно, является более читаемым и более удобным для обслуживания. Просто убедитесь, что вы не добавите скобки, где разбивают порядок обратной ссылки (первая скобка создает первую группу \1, второй \2 и т.д.)

sed -r 's/([^ ]+([ ]+[^ ]+){2}).*/\1/' file 

Обратите внимание, как вторая группа в скобках необходимо укажите область повторения {2} (мы хотим повторить больше, чем просто одиночный символ непосредственно перед левой фигурной скобкой). У попытки OP была ошибка, когда повторение было указано вне последней скобки; то обратная ссылка \1 (или что бы там ни называлось на вашем диалекте - TextMate, похоже, использует $1, как и Perl) будет ссылаться на последнее единственное совпадение скобок, поскольку повторение не является частью захвата, находясь вне скользящие круглые скобки.

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