2

В Python 3 довольно просто извлечь текст из именованных групп, как показано в следующем примере:

import re
myStr = r"4000/2000/5000/7000"
reObj = re.compile(r"""(?P<g1>\d+)  # a capturing group named g1
                       /
                       (?P<g2>\d+)
                       /
                       (?P<g3>\d+)
                       /
                       (?P<g4>\d+)""", re.VERBOSE) 
matchObj = reObj.match(myStr)  # match the string to be searched
print(matchObj.group("g1"))  # 4000
print(matchObj.group("g2"))  # 2000 
print(matchObj.group("g3"))  # 5000 
print(matchObj.group("g4"))  # 7000

Однако в LibreOffice Calc я просто не мог получить никакой подсказки (у Calc даже нет независимой функции regex (), которая дает шаблон регулярного выражения). Основанные на позиции обходные пути, как в этом посте , не то, что мне нужно.

ПОЖАЛУЙСТА, ДАЙТЕ ОТВЕТЫ, НЕЗАВИСИМЫЕ ОТ ПОЗИЦИОННЫХ ПАРАМЕТРОВ, И ПОЖАЛУЙСТА, ОБЪЯСНИТЕ ЯВНО. например, MID() недопустимо. Хотя приведенный здесь пример достаточно прост, но мне нужен общий способ справиться с реальной ситуацией, которая намного сложнее.

2 ответа2

6

И в Excel, и в Calc самое чистое решение - создать макрос регулярного выражения общего назначения. Чтобы сделать это в Calc, перейдите в Tools -> Macros -> Organize Macros -> LibreOffice Basic и добавьте следующий код в Module1:

Function ReFind(findIn, patt, Optional group_param As Integer,  _
                Optional ignoreCase_param As Boolean)
    ' findIn - string or cell to search in
    ' patt - regexp string or cell containing regexp string
    ' group - which group to grab - analogy to \n in regexp syntax
    ' ignoreCase - false for case sensitive matches
    If IsMissing (group_param) Then
        group = 0
    Else
        group = group_param
    End If
    If IsMissing (ignoreCase_param) Then
        ignoreCase = False
    Else
        ignoreCase = ignoreCase_param
    End If
    oTextSearch = CreateUnoService("com.sun.star.util.TextSearch")
    oOptions = CreateUnoStruct("com.sun.star.util.SearchOptions")
    oOptions.algorithmType = com.sun.star.util.SearchAlgorithms.REGEXP
    If ignoreCase Then
        oOptions.transliterateFlags = _
            com.sun.star.i18n.TransliterationModules.IGNORE_CASE
    End If
    oOptions.searchString = patt
    oTextSearch.setOptions(oOptions)
    oFound = oTextSearch.searchForward(findIn, 0, Len(findIn))
    If oFound.subRegExpressions = 0 Then
        ReFind = "No results"
        MsgBox "No results"
        Exit Function
    ElseIf group >= oFound.subRegExpressions Then 
         ReFind = "No result for that group"
         MsgBox "No result for that group"
         Exit Function
    Else
         nStart = oFound.startOffset()
         nEnd = oFound.endOffset()
         ReFind = Mid(findIn, nStart(group) + 1, nEnd(group) - nStart(group))
    End If
End Function

Теперь вы можете использовать ReFind для любых регулярных выражений, необходимых в электронной таблице. Например, в ячейку A1 введите 12345 . В ячейку B1 введите формулу =REFIND($A$1,"(\d\d)(\d)",2) . Это восстановит третье число, которое равно 3.

Код был адаптирован с https://forum.openoffice.org/en/forum/viewtopic.php?t=30502.

Примечание. Было бы лучше создать регулярное выражение в python или java с помощью надстройки. Однако для этого требуются файлы декларации XML с расширением, которое требует больше времени для настройки.

1

AFAIK, вы не можете использовать именованные группы в LO Calc Search/Replace или формулах, но вы можете использовать числовые ссылки на группы шаблонов:

  • В поле поиска вы можете использовать \1 для ссылки на первую группу шаблонов, \2 для второй и так далее.
  • В выражении замены используйте $1 качестве ссылки для первой группы шаблонов поиска, $2 для второй и так далее.

Пример поиска

Предполагая, что четыре строки blue bluefish , black blackfish , blue blackfish и black bluefish , вы можете заменить каждую строку, где один и тот же цвет появляется дважды (строки 1 и 2), используя шаблон поиска: (blue|black) \1fish . \1 будет ссылаться на соответствующую группу, соответствующую всей строке, только если цвет, соответствующий группе регулярных выражений (blue|black) появляется перед fish . (Пример основан на документации OOo Wiki).

Заменить пример

Чтобы преобразовать строку 100/200/300/400 в 300/100/400/200 (с включенным регулярным выражением в параметрах поиска), найдите шаблон (\d+)/(\d+)/(\d+)/(\d+) и заменить на $3/$1/$4/$2 .

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .