Обрезка строки с пробелами - PullRequest
3 голосов
/ 17 мая 2011

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

Предположим, у меня есть такое имя

Mr. John Doe
John Smith.

В обоих случаях я бы хотел получить только имя строки и удалить все остальные символы.

Таким образом, для обеих строк после их анализа будет John в них

Мне было интересно, есть ли способ решить эту проблему с помощью регулярных выражений.

Ответы [ 5 ]

6 голосов
/ 18 мая 2011

Вы не можете сделать это. Не без раздражения некоторых людей, потому что вы искали их имя. Вы не можете различить Джона Пола Доу (имя «Джон», отчество «Пол», фамилия «Доу»), Джон Джозеф Браун (ответы на «Джозеф» или «Джо», но только когда-либо использует «Джон» на формы правительства) и Джон Пол Смит (имя «Джон Пол» и ненавидит его сокращать).

Читайте Программисты лжи верят в имена .

Тогда иди и прочитай это снова, и на этот раз признай, что да, 95% населения мира совершенно другое представление о том, какое имя у вас. (80%, если вы китаец.)

Самое большее, что вы можете сделать, это обрезать пробелы и, возможно, несколько «безопасных» префиксов, таких как «Мистер» - и я бы даже этого не сделал (если бы люди потрудились написать «Мистер», они, вероятно, хотели бы иметь его). есть).

s/^\s+//; s/\s+$//;     # trim whitespace at each end
s((\s+))(               # trim embedded whitespace
    $1=~/[^\x{a0}]/ ?   # breakable?
    " " : "\x{a0}")ge;
1 голос
/ 18 мая 2011

Вот простое регулярное выражение, которое будет соответствовать обоим случаям

/^(?:\w+\.)?\s*(\w+).*$/
// $1 = John

Вы можете создать его так:
\w+\. хотя бы один символ слова, за которым следует точка (для префикса имени)
(\w+\.)? группа может появиться один раз или не появляться вообще
(?:\w+\.)? группа не захватывает (нам это не нужно)
^(?:\w+\.)? ^ сигнализирует о начале всей строки (поэтому эта группа является первой в ней) ^(?:\w+\.)?\s* за этой группой префиксов может следовать любое количество пробелов (или ни одного)
^(?:\w+\.)?\s*(\w+) затем следует группа для имени (которая состоит как минимум из одного символа слова)
^(?:\w+\.)?\s*(\w+).*$ наконец .* соответствует остальным символам до конца строки $

1 голос
/ 17 мая 2011

Попробуйте это, ваше имя в первой группе захвата $ 1.

^(?:Mr\.|Mrs\.)?\s*\b([^\s]*)\b.*$

Посмотреть онлайн здесь на Regexr

0 голосов
/ 17 мая 2011

Я думаю, что это будет работать

my $nameFull = 'Mr. John Doe';
my $nameFirst = $1 if $nameFull =~ /(?:\s|^)(?!(?:mr|mr?s|miss|dr|prof)(?![a-z]))([a-z]+)/i;

Объяснено:

/ ... /i Начало и конец регулярного выражения без учета регистра

  • (?:\s|^) Убедитесь, что мы находимся либо в пробеле, либо в начале строки.
  • (?! ... ) Убедитесь, что это не будет совпадать в начале имени
    • (?:mr|mr?s|miss|dr|prof) Список сокращений (r? означает необязательный r, поэтому он будет соответствовать Ms и Mrs)
    • (?![a-z]) Убедитесь, что больше нетбукв сразу после аббревиатуры, потому что drake - это имя, которое начинается с dr
  • ( ... ) Захватите это как $1
    • [a-z]+ Столько букв, сколько в строке.Предположим, по крайней мере, один.
0 голосов
/ 17 мая 2011

Сколько разных форматов вы хотите принять?

Вот тот, который должен работать для двух вы опубликовали:

/(?<=((Mr\.|Mrs\.)\s+)?)([a-zA-Z]+)/
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...