Регулярное выражение, чтобы убрать одинарные кавычки и сохранить апострофы - PullRequest
2 голосов
/ 21 марта 2012

Я хочу разобрать слова из текстового файла.Апострофы должны быть сохранены, но одинарные кавычки должны быть удалены.Вот некоторые тестовые данные:

john's apostrophe is a 'challenge'

Я экспериментирую с grep следующим образом:

grep -o "[a-z'A-Z]*" file.txt

и он выдает:

john's
apostrophe
is
a
'challenge'

Необходимо избавиться отэти цитаты вокруг слова challenge.

Правильный / желаемый результат должен быть:

john's
apostrophe
is
a
challenge

РЕДАКТИРОВАТЬ: Поскольку консенсус кажется, что апострофы проблематично распознать, я сейчас ищу способ убрать любой апостроф(ведущий, конечный, встроенный) из всех слов.Слова должны быть добавлены в словарный указатель.Поиск фразы также должен убрать апострофы.Это может понадобиться еще один вопрос.

Ответы [ 2 ]

4 голосов
/ 22 марта 2012

Вот более простой grep -только подход:

grep -E -o "[a-zA-Z]([a-z'A-Z]*[a-zA-Z])?" file.txt

который в Java:

Pattern.compile("[a-zA-Z]([a-z'A-Z]*[a-zA-Z])?")

(оба из них означают «букву ASCII, за которой, возможно, следует комбинация букв ASCII и / или апострофов и буквы ASCII». но если его длина более двух символов, он может содержать апострофы.)

Чтобы принимать не-ASCII буквы, Java можно записать как:

Pattern.compile("\\p{L}([\\p{L}']*\\p{L})?")

Изменить для обновленного вопроса (убрав апострофы): я не думаю, что вы можете сделать это с просто grep; но немного расширив наш репертуар, вы можете написать:

tr -d "'" file.txt | grep -E -o "[a-zA-Z]+"

или на Java:

String apostrippedStr = str.replace("'", "");

Pattern.compile("[a-zA-Z]+") // or "\\p{L}+" for non-ASCII support
// ... apply pattern to apostrippedStr
4 голосов
/ 22 марта 2012

Вам нужно использовать grep? Вот пример sed на всякий случай:

$ echo "john's apostrophe is a 'challenge'" | sed -re "s/'(\S*)'/\1/g"
john's apostrophe is a challenge

sed - это потоковый редактор, я использовал его для подстановки (формат s/pattern/subst/, g обозначает глобальный. Я сопоставляю произвольное число (*) непробельных символов (\S) и замените его той же группой символов, обозначив ее как \1 (я запечатлел ее в круглых скобках (...).

Редактировать: Хорошо, вот уродливый Perl-подобный grep пример:

$ echo "john's apostrophe is a 'challenge'" | grep -oP "(?<=')\S*(?=')|\w+'?\w*"
john's
apostrophe
is
a
challenge

Понятия не имею, что я сделал, так что неожиданное поведение вероятно:)

С помощью grep я использовал положительные обратные утверждения для сопоставления либо слово в одинарных кавычках (утверждения используются для того, чтобы кавычки не были частью совпадения) или (|) слово с необязательным апострофом, которое представлено «одним или несколькими символами слова» (\w+), за которыми следует ' (или нет), а затем, при необходимости, снова некоторые символы слова .

Подробнее: вот команда sed, которая, кажется, выполняет эту работу и справляется с примером @ tchrist:

$ echo "john's apostrophe is a 'challenge'" | sed -re "s/(\W|^) '(\w*)'(\W|$)/\1\2\3/g"
john's apostrophe is a challenge
$ echo "’Tis especially hard, ’tisn’t it now, to leave it for the dogs’ breakfast, let a lone for the cats'" | sed -re "s/(\W|^)'(\w*)'(\W|$)/\1\2\3/g"
’Tis especially hard, ’tisn’t it now, to leave it for the dogs’ breakfast, let a lone for the cats'
...