Extraindo grupos nomeados de expressão regular no LibreOffice Calc

2

No Python 3, é muito fácil extrair texto de grupos nomeados, conforme mostrado no exemplo a seguir:

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

No entanto, no LibreOffice Calc, eu simplesmente não conseguia obter nenhuma pista (o Calc não tem sequer uma função regex () independente que forneça um padrão de expressão regular). Soluções alternativas baseadas na posição como em este post não são o que eu preciso.

POR FAVOR, DÊ RESPOSTAS INDEPENDENTES DE PARÂMETROS POSICIONAIS E POR FAVOR EXEMPLIFICAR EXPLICITAMENTE. por exemplo. MID () não é aceitável. Embora o exemplo dado aqui seja simples o suficiente, mas eu preciso de uma maneira geral de lidar com uma situação real que é muito mais complexa.

    
por cbhuang 02.05.2016 / 09:56

2 respostas

6

No Excel e no Calc, a solução mais limpa é criar uma macro de expressão regular de propósito geral. Para fazer isso no Calc, acesse Tools -> Macros -> Organize Macros -> LibreOffice Basic e adicione o seguinte código ao Módulo1:

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

Agora você pode usar ReFind para quaisquer expressões regulares necessárias na planilha. Por exemplo, na célula A1, insira 12345 . Na célula B1, insira a fórmula =REFIND($A$1,"(\d\d)(\d)",2) . Isso recuperará o terceiro número, que é 3.

O código foi adaptado do link .

Observação: seria melhor criar a expressão regular em python ou java usando um suplemento. em . No entanto, isso requer arquivos de declaração XML em uma extensão, o que leva mais tempo para ser configurado.

    
por 02.05.2016 / 17:32
1

AFAIK você não pode usar grupos nomeados em LO Calc Search / Replace ou fórmulas, mas você pode usar referências numéricas para grupos de padrões:

  • No campo pesquisa , você pode usar para fazer referência ao primeiro grupo padrão, para o segundo e assim por diante.
  • Na expressão replace , use $1 como referência para o primeiro grupo de padrões de pesquisa, $2 para o segundo e assim por diante.

Exemplo de pesquisa

Supondo que as quatro strings blue bluefish , black blackfish , blue blackfish e black bluefish , você pode substituir todas as cadeias nas quais a mesma cor aparece duas vezes (strings 1 e 2) usando o padrão de pesquisa: (blue|black) fish . O fará referência ao grupo correspondente, correspondendo a sequência inteira somente se a cor correspondida no grupo de expressões regulares (blue|black) aparecer antes de fish também. ( Exemplo baseado na documentação do Wiki do OOo ) .

Substituir exemplo

Para transformar a string 100/200/300/400 em 300/100/400/200 (com a regex ativada nas opções de pesquisa), procure o padrão (\d+)/(\d+)/(\d+)/(\d+) e substitua por $3/$1/$4/$2 .

    
por 02.05.2016 / 11:17