Регулярное выражение делает заглавными первую букву слов, превышающую 3 символа, и после дефисов и апострофов.

В основном ...

Я пытаюсь ввести в строке собственный регистр; Я потратил несколько часов на борьбу с Regex безрезультатно ...

Требование:

Мне нужно использовать заглавные буквы:

  1. Если первое слово> 3 символов: первая буква первого слова.
  2. Если последнее слово> 3 символа: первая буква последнего слова.
  3. Всегда: первая буква после дефиса или апострофа.

(Последнее регулярное выражение должно быть реализовано в VB6)

Examples:
anne-marie          >  Anne-Marie          // 1st letter of first word + after hyphen
vom schattenreich   >  vom Schattenreich   // 1st letter of last word
will it work-or-not >  Will it Work-Or-Not // 1st letter of outer words + after hyphens
seth o'callaghan    >  Seth O'Callaghan    // 1st letter of outer words + after apostrophe
first and last only >  First and last Only // 1st letter of outer words (excl. middle)
sarah jane o'brien  >  Sarah jane O'Brien  // 1st letter of outer words (excl. middle)

Что у меня есть на данный момент:

Я смешал два регулярных выражения, которые почти могут выполнить то, что мне нужно. Однако мои попытки объединить их или написать как единое регулярное выражение потерпели неудачу.

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

Мое регулярное выражение:

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

^([a-zA-Z]).*\s([a-zA-Z])[a-zA-Z-]+$

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

(\b[a-zA-Z](?=[a-zA-Z-']{3}))

Вопрос

Как я могу объединить эти два регулярных выражения для удовлетворения моих требований или исправить их достаточно, чтобы их можно было использовать по отдельности? В качестве альтернативы предоставьте другое регулярное выражение, отвечающее требованиям.

Справочный / соответствующий исходный материал:

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

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


person Matthew Hudson    schedule 14.06.2016    source источник


Ответы (1)


Вот мой подход с одним регулярным выражением:

Sub ReplaceAndTurnUppercase()

Dim reg As RegExp
Dim res As String

Set reg = New RegExp
With reg
    .Pattern = "^[a-z](?=[a-zA-Z'-]{3})|\b[a-zA-Z](?=[a-zA-Z'-]{3,}$)|['-][a-z]"
    .Global = True
    .MultiLine = True
End With
s = "anne-marie" & vbCrLf & "vom schattenreich" & vbCrLf & "will it work-or-not" & vbCrLf & "seth o'callaghan" & vbCrLf & "first and last only" & vbCrLf & "sarah jane o'brien"
res = s
For Each Match In reg.Execute(s)
    If Len(Match.Value) > 0 Then
        res = Left(res, Match.FirstIndex) & UCase(Match.Value) & Mid(res, Match.FirstIndex + Len(Match.Value) + 1)
    End If
Next Match
Debug.Print res ' Demo part

End Sub

введите описание изображения здесь

Я использую регулярное выражение ^[a-z](?=[a-zA-Z'-]{3})|\b[a-z](?=[a-zA-Z'-]{3,}$)|['-][a-z]. Поскольку все используемые символы - это просто буквы, которые мы хотим преобразовать в верхний регистр или дефис / апостроф, мы можем преобразовать их все в верхний регистр, не заботясь о захвате любого из них.

Регулярное выражение соответствует 3 альтернативам:

  • ^[a-z](?=[a-zA-Z'-]{3}) - начало строки (в моем случае это строка с тех пор, как я использовал Multiline=True), за которой следует строчная буква ASCII (используется, чтобы быть в верхнем регистре позже), которая имеет 3 символа после нее, буквы или ' или - (не используются, внутри предварительного просмотра )
  • \b[a-z](?=[a-zA-Z'-]{3,}$) - граница слова \b, за которой следует строчная буква ASCII (использованная), за которой следует 3 или более букв или ' или - до конца строки (строка в моем случае)
  • ['-][a-z] - соответствует ' или -, а затем строчной букве (в любом месте строки).

Строка res = Left(res, match.FirstIndex) & UCase(match.Value) & Mid(res, match.FirstIndex + Len(match.Value) + 1) выполняет свою работу: она просто получает часть строки до найденного индекса, затем добавляет измененный текст и добавляет остальную часть.

person Wiktor Stribiżew    schedule 14.06.2016
comment
спасибо за оперативный ответ, очень близко! К сожалению, мне нужно сопоставить только первое и последнее слово, содержащее более 3 символов. См. regex101.com/r/mX4wH6/3. - person Matthew Hudson; 14.06.2016
comment
Не могли бы вы тогда обновить образцы входных текстов? Я проверял это только с теми, что вы разместили. - person Wiktor Stribiżew; 14.06.2016
comment
Нельзя ли с этим справиться с помощью другого операционной? (Пожалуйста, простите меня за отсутствие знаний о регулярных выражениях) - person Matthew Hudson; 14.06.2016
comment
Похоже, я переоценил сложность регулярного выражения :) - person Wiktor Stribiżew; 14.06.2016