AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / coding / Perguntas / 79195042
Accepted
RavinderSingh13
RavinderSingh13
Asked: 2024-11-16 19:20:41 +0800 CST2024-11-16 19:20:41 +0800 CST 2024-11-16 19:20:41 +0800 CST

Manipulando estruturas complexas de parênteses para obter os dados esperados

  • 772

Temos dados de uma chamada de API REST armazenados em um arquivo de saída que se parece com o seguinte:

Arquivo de entrada de exemplo:

test test123 - test (bla bla1 (On chutti))
test test123 bla12 teeee (Rinku Singh)
balle balle (testagain) (Rohit Sharma)
test test123 test1111 test45345 (Surya) (Virat kohli (Lagaan))
testagain blae kaun hai ye banda (Ranbir kapoor (Lagaan), Milkha Singh (On chutti) (Lagaan))

Saída esperada:

bla bla1
Rinku Singh
Rohit Sharma
Virat kohli
Ranbir kapoor, Milkha Singh

Condições para derivar a saída esperada:

  • Considere sempre a última ocorrência de parênteses () em cada linha. Precisamos extrair os valores dentro deste último par de parênteses mais externo.
  • Dentro da última ocorrência de (), extraia todos os valores que aparecem antes de cada ocorrência de parênteses aninhados ().
  • Por exemplo: test test123 - test (bla bla1 (On chutti))o último parêntesis começa de (blaaté até, chutti))então preciso, bla bla1pois é antes de inner (On chutti). Então, procure o último parêntesis e, em seguida, dentro de quantos pares de parêntesis vêm, precisamos obter dados antes deles, por exemplo: na linha testagain blae kaun hai ye banda (Ranbir kapoor (Lagaan), Milkha Singh (On chutti) (Lagaan))necessário é Ranbir kapoore Milkha Singh.

Tentativa de expressão regular: Tentei usar a seguinte expressão regular na demonstração funcional do regex :

Expressão regular:

^(?:^[^(]+\([^)]+\) \(([^(]+)\([^)]+\)\))|[^(]+\(([^(]+)\([^)]+\),\s([^\(]+)\([^)]+\)\s\([^\)]+\)\)|(?:(?:.*?)\((.*?)\(.*?\)\))|(?:[^(]+\(([^)]+)\))$

O Regex que testei está funcionando bem, mas quero melhorá-lo com o conselho de especialistas aqui.

Idiomas Preferidos: Procurando melhorar este regex OU um python, a resposta awk também está ok. Eu mesmo também tentarei adicionar uma awkresposta.

python
  • 8 8 respostas
  • 202 Views

8 respostas

  • Voted
  1. Pierre couy
    2024-11-16T20:44:07+08:002024-11-16T20:44:07+08:00

    Geralmente, expressões regulares não são apropriadas para analisar conjuntos aninhados de parênteses.

    Aqui está um pequeno script Python que faz o que você pediu:

    import fileinput
    
    for line in fileinput.input():
        line_result = ""
        parenthesis_level = 0 # Keeps track of how deep we are inside the parenthesis
        for char in line:
            if char == ")":
                parenthesis_level -= 1
            if parenthesis_level == 1 and char not in "()":
                line_result += char
            if char == "(":
                if parenthesis_level == 0: # Only keep the last outermost parenthesis
                    line_result = "" # Discard any result from previous top-level parenthesis
                parenthesis_level += 1
        print(line_result)
    

    Eu usei fileinputpara este PoC, mas deve ser trivial substituí-lo por qualquer que seja sua fonte de dados. Eu tentei com:

    echo "test test123 - test (bla bla1 (On chutti))
    test test123 bla12 teeee (Rinku Singh)
    balle balle (testagain) (Rohit Sharma)
    test test123 test1111 test45345 (Surya) (Virat kohli (Lagaan))
    testagain blae kaun hai ye banda (Ranbir kapoor (Lagaan), Milkha Singh (On chutti)" | python test.py
    

    e obtive o seguinte resultado:

    bla bla1
    Rinku Singh
    Rohit Sharma
    Virat kohli
    Ranbir kapoor , Milkha Singh
    

    Bônus:

    Como forma de enfatizar a não utilização de regex para esse tipo de propósito, fiz um pouco de golfe de código e encurtei o script acima para o seguinte:

    import fileinput as i
    for l in i.input():
     p=0
     for c in l:
      if c==")":p-=1
      if p==1 and c not in "()":r+=c
      if c=="(":
       if p==0:r=""
       p+= 1
     print(r)
    

    Ignorando a linha de importação (mas ainda contando todos os caracteres abaixo, incluindo recuos e retornos de linha), isso tem 136 caracteres de comprimento, 14 caracteres a menos que a expressão regular mostrada na pergunta. Esse código Python encurtado é (na minha opinião) ainda mais legível/manutenível/extensível do que qualquer regex que alguém possa inventar.

    • 7
  2. markp-fuso
    2024-11-17T01:38:32+08:002024-11-17T01:38:32+08:00

    Suposições/entendimentos:

    • parênteses ( (, )) existem apenas como delimitadores (ou seja, não aparecem como parte dos dados)
    • cada um (tem uma correspondência)
    • level=1 consiste em todo o texto que não está entre parênteses
    • cada sucessivo (nos leva um nível abaixo
    • cada sucessivo )nos leva um nível acima
    • para o nível N (N>1) devemos exibir apenas o último conjunto de dados correspondente (por exemplo, se houver 2 conjuntos distintos de dados de nível=2, então exibiremos apenas o último conjunto de dados)
    • a descrição textual não corresponde ao regex atual do OP com relação a quais caracteres estranhos devem ser removidos (por exemplo, remover vírgulas, remover espaços finais, reduzir vários espaços a um único espaço, etc.); [ NOTA: não está claro (para mim) o que isso significa: There is NO separator in output since in Python it was coming in capturing groups. In case of awk OR without capturing group's solution, can be separated with ,]; para uma solução inicial, não removeremos nada; o OP sempre pode adicionar código para remover caracteres estranhos

    Ampliando o conjunto de dados atual do OP:

    $ cat input.dat
    flat line
    test test123 - test (bla bla1 (On chutti)) _ level 1
    test test123 bla12 teeee (Rinku Singh)
    balle balle (testagain) (Rohit Sharma)
    test test123 test1111 test45345 (Surya) (Virat kohli (Lagaan))
    testagain blae kaun hai ye banda (Ranbir kapoor (Lagaan1), Milkha Singh (On chutti) (Lagaan2))
    a (b c) (d (e f), g (h i), j) k
    1 (2 (3 (4 (5 5)), 3), 2 ), 1
    

    Demonstração de níveis:

    1 (2 (3 (4 (5 5)), 3), 2 ), 1
    ^^                        ^^^ - level 1
       ^^                ^^^^     - level 2
          ^^         ^^^          - level 3
             ^^                   - level 4
                ^^^               - level 5
    

    Demonstração dos últimos dados do nível 2:

    balle balle (testagain) (Rohit Sharma)
    ^^^^^^^^^^^^           ^               - level 1
                 ^^^^^^^^^                 - level 2 (first occurrence)
                             ^^^^^^^^^^^^  - level 2 (last occurrence)
    

    Uma awkideia usando uma função recursiva para analisar dados delimitados por parênteses:

    awk -v lvl=2 '                                          # level to display
    function parse(line, cur_lvl,    pos, char) {
        if (line == "") return
        pos  = match(line,/[()]/)                           # find 1st "(" or ")"
        char = (pos>0 ? substr(line,pos,1) : "")            # "(" or ")" ?
    
        if ((cur_lvl+1) == lvl && char == "(")              # if new level (>1) data set then ...
           out = ""                                         # clear previous data set
    
        if (cur_lvl == lvl) {                               # if at desired level then ...
           if (pos == 0) { out = out line; return }         # append; no more parens so go "up" in call stack
           else          out = out substr(line,1,pos-1)     # append
        }
        if (pos > 0)                                        # if we found a paren then recurse:
           parse(substr(line,pos+1), (char == "(" ? cur_lvl+1 : cur_lvl-1))
    }
    
    { out     = ""                                          # init output
      cur_lvl = 1                                           # init starting level
      line    = $0                                          # make copy of $0
    
      parse(line, cur_lvl)                                  # start parsing
    
      ###  add code here to remove extraneous characters ?
    
      if (out != "")                                        # if we have something to print ...
         print ":" out ":"                                  # colons are added for display purposes; OP can remove once satisfied with results
    }
    ' input.dat
    

    Outra awksolução usando uma abordagem linear para análise sintática (semelhante à solução python de Pierre)

    awk -v lvl=2 '
    { out     = "" 
      cur_lvl = 1
      line    = $0
    
      while (pos = match(line,/[()]/)) {
            char = (pos>0 ? substr(line,pos,1) : "")
            if (cur_lvl == lvl) out = out substr(line,1,pos-1)
            if (char    == "(") { cur_lvl++; out = (cur_lvl==lvl ? "" : out) }
            if (char    == ")") cur_lvl-- 
            line = substr(line,pos+1) 
      }
    
      if (cur_lvl == lvl) out = out line
      if (    out != "" ) print ":" out ":" 
    }
    ' input.dat
    

    Fazendo um teste (ambas as awksoluções acima geram a mesma saída, considerando a mesma lvlconfiguração):

    Para lvl=2(solicitação do OP):

    :bla bla1 :
    :Rinku Singh:
    :Rohit Sharma:
    :Virat kohli :
    :Ranbir kapoor , Milkha Singh  :
    :d , g , j:
    :2 , 2 :
    

    Para lvl=1:

    :flat line:
    :test test123 - test  _ level 1:
    :test test123 bla12 teeee :
    :balle balle  :
    :test test123 test1111 test45345  :
    :testagain blae kaun hai ye banda :
    :a   k:
    :1 , 1:
    

    Para lvl=3:

    :On chutti:
    :Lagaan:
    :Lagaan2:
    :h i:
    :3 , 3:
    

    Para lvl=5:

    :5 5:
    

    Para lvl=6:

             # no output
    
    • 5
  3. Ed Morton
    2024-11-16T20:15:12+08:002024-11-16T20:15:12+08:00

    Sempre que você estiver pensando em usar uma expressão regular longa e/ou complicada para tentar resolver um problema, tenha em mente a citação :

    Algumas pessoas, quando confrontadas com um problema, pensam: "Eu sei, vou usar expressões regulares". Agora elas têm dois problemas.

    Usando qualquer awk:

    $ cat tst.awk
    {
        rec = $0
        while ( match(rec, /\([^()]*)/) ) {
            tgt = substr($0,RSTART+1,RLENGTH-2)
            rec = substr(rec,1,RSTART-1) RS substr(rec,RSTART+1,RLENGTH-2) RS substr(rec,RSTART+RLENGTH)
        }
        gsub(/ *\([^()]*) */, "", tgt)
        print tgt
    }
    

    $ awk -f tst.awk file
    bla bla1
    Rinku Singh
    Rohit Sharma
    Virat kohli
    Ranbir kapoor, Milkha Singh
    

    Estou salvando uma cópia de $0in rece, então, no loop, estou convertendo cada (foo)inside recpara \nfoo\n(assumindo o padrão RSe que o RSnão pode estar presente em um RSregistro separado por -) e também salvando o foofrom $0(para reter os pares originais (e possivelmente aninhados )) na variável tgt. Então, quando o loop termina, tgtcontém a última foosubstring que estava presente neste registro de entrada, por exemplo Ranbir kapoor (Lagaan), Milkha Singh (On chutti) (Lagaan), . Então, com o final, gsub()removo todas (...)as substrings de tgt, incluindo quaisquer espaços em branco ao redor, deixando apenas a saída desejada.

    Se você puder ter mais níveis de strings entre parênteses restantes tgtdo que apenas 1 nível de profundidade, basta mudar gsub(/ *\([^()]*) */, "", tgt)para while ( gsub(/ *\([^()]*) */, "", tgt) );.

    • 4
  4. Best Answer
    anubhava
    2024-11-16T22:37:17+08:002024-11-16T22:37:17+08:00

    Com base apenas na entrada mostrada e nos seus comentários refletindo que você precisa capturar 1 ou 2 valores por linha, aqui está uma solução de regex otimizada:

    ^(?:\([^)(]*\)|[^()])*\(([^)(]+)(?:\([^)(]*\)[, ]*(?:([^)(]+))?)?
    

    Demonstração RegEx

    Detalhes do RegEx:

    Esta solução regex faz o seguinte:

    • combine tudo antes do último (...) então combine (então
    • 1º grupo: nome da correspondência que não deve ter ( e ) então
    • correspondência opcional de (...) ou vírgula/espaço então
    • 2º grupo: nome da partida que não deve ter ( e )

    Mais detalhes:

    • ^: Começar
    • (?:: Iniciar grupo de não captura
      • \([^\n)(]*\): Corresponde a qualquer par de (...)texto
      • |: OU
      • [^()\n]: Corresponde a qualquer caractere que não seja (, )e\n
    • )*: Fim do grupo de não captura. Repita isso 0 ou mais vezes
    • \(: Última partida(
    • ([^)(\n]+): 1º grupo de captura que corresponde ao texto com 1+ caracteres que não são (, )e\n
    • (?:: Iniciar grupo de não captura 1
      • \([^\n)(]*\): Corresponde a qualquer par de (...)texto
      • [, ]*: Corresponde a 0 ou mais caracteres de espaço ou vírgula
      • (?:: Iniciar grupo de não captura 2
        • ([^)(\n]+): 2º grupo de captura que corresponde ao texto com 1+ caracteres que não são (, )e\n
      • )?: Fim do grupo de não captura 2. ?torna esta uma correspondência opcional
    • )?: Fim do grupo de não captura 1. ?torna esta uma correspondência opcional
    • 4
  5. anubhava
    2024-11-16T23:15:54+08:002024-11-16T23:15:54+08:00

    Aqui está minha awksolução simples que funciona apenas com as substituições:

    cat srch.awk
    
    {
       gsub(/^(\([^)(]*\)|[^()])*\(/, "");
       gsub(/ *\([^(]*\) */, "")
       sub(/[) ]*$/, "")
    }
    1
    

    Em seguida, execute-o como:

    awk -f srch.awk file
    
    bla bla1
    Rinku Singh
    Rohit Sharma
    Virat kohli
    Ranbir kapoor, Milkha Singh
    
    • 2
  6. The fourth bird
    2024-11-17T22:24:25+08:002024-11-17T22:24:25+08:00

    Se você estiver aberto a usar Python com o módulo regex PyPi, você pode usar nomes de grupos duplicados e então usar captures("groupname")para retornar uma lista de todas as capturas de um grupo.

    Esta regex pressupõe que há no máximo 1 nível de aninhamento onde pode haver 1 ou mais ocorrências do mesmo nome de grupo naquele nível.

    \((?P<grp>[^()]+)(?:\([^()]*\)(?:,\s+(?P<grp>[^()]+)(?:\s*\([^()]*\))*)*)?\)$
    

    A expressão regular corresponde a:

    • \(Corresponder(
    • (?P<grp>[^()]+)Nomeado grppara combinar com(...)
    • (?:Grupo de não captura
      • \([^()]*\)
      • (?:Grupo de não captura
        • ,\sCorresponder a uma vírgula e 1+ caracteres de espaço em branco
        • (?P<grp>[^()]+)Nomeado grppara combinar com(...)
        • (?:\s*\([^()]*\))*Opcionalmente, combine 0+ caracteres de espaço em branco seguidos por(...)
      • )*Feche o grupo de não captura
    • )?Feche o grupo e torne-o opcional
    • \)Corresponder)
    • $Fim da sequência

    Veja uma demonstração de regex e uma demonstração de Python

    Exemplo

    import regex
    
    strings = [
        "test test123 - test (bla bla1 (On chutti))",
        "test test123 - abc (test1 (test2)) test (bla bla1 (On chutti))",
        "test test123 bla12 teeee (Rinku Singh)",
        "balle balle (testagain) (Rohit Sharma)",
        "test test123 test1111 test45345 (Surya) (Virat kohli (Lagaan))",
        "testagain blae kaun hai ye banda (Ranbir kapoor (Lagaan), Milkha Singh (On chutti) (Lagaan))",
        "testagain blae kaun hai ye banda (Ranbir kapoor (Lagaan), Ranbir kapoor (Lagaan), Milkha Singh (On chutti))",
        "testagain blae kaun hai ye banda (Ranbir kapoor (Lagaan), Ranbir kapoor (Lagaan), Test 1 (Test 2) (Test 3))"
    ]
    
    pattern = r"\((?P<grp>[^()]+)(?:\([^()]*\)(?:,\s(?P<grp>[^()]+)(?:\s*\([^()]*\))*)*)?\)$"
    
    for s in strings:
        match = regex.search(pattern, s)
        if match:
            print(match.captures("grp"))
    

    Saída

    ['bla bla1 ']
    ['bla bla1 ']
    ['Rinku Singh']
    ['Rohit Sharma']
    ['Virat kohli ']
    ['Ranbir kapoor ', 'Milkha Singh ']
    ['Ranbir kapoor ', 'Ranbir kapoor ', 'Milkha Singh ']
    ['Ranbir kapoor ', 'Ranbir kapoor ', 'Test 1 ']
    

    Algumas pequenas adições

    • Esta não é uma solução infalível, pois a correspondência de parênteses pode ser muito complicada
    • Uma parte como (?:.*?)é o mesmo que .*?Você pode omitir o grupo não capturado em algumas subpartes do seu regex, já que o grupo por si só não está sendo usado para uma alternância e não há quantificadores para esse grupo
    • Observe que uma parte como esta .*?\)\)corresponde ao menor número possível de caracteres, seguida por ))onde o .*próprio também pode corresponder a parênteses, onde pode corresponder involuntariamente a muitos
    • Olhando para o regex que você tentou no modo estendido, você pode ver que está usando 4 alternâncias onde apenas a primeira e a última alternativa estão ancoradas. Usar grupos de captura como este em branches separados pode lhe dar (em Python, por exemplo) correspondências vazias para todos os grupos que não têm correspondência
    • 2
  7. dawg
    2024-11-17T23:20:18+08:002024-11-17T23:20:18+08:00

    Você pode usar nestedExpro módulo PyParsing :

    from pyparsing import nestedExpr
    import re 
    
    txt='''\
    test test123 - test (bla bla1 (On chutti))
    test test123 bla12 teeee (Rinku Singh)
    balle balle (testagain) (Rohit Sharma)
    test test123 test1111 test45345 (Surya) (Virat kohli (Lagaan))
    testagain blae kaun hai ye banda (Ranbir kapoor (Lagaan), Milkha Singh (On chutti) (Lagaan))
    '''
    
    brace_parser = nestedExpr()
    
    for line in txt.splitlines():
        new_line=re.sub(r'^[^(]*|[^)]*$', '', line)
        for m in brace_parser.parseString(new_line):
            stack=[]
            for e in m:
                if isinstance(e, str): stack.append(e)
            print(' '.join(stack))   
    

    Impressões:

    bla bla1
    Rinku Singh
    testagain
    Surya
    Ranbir kapoor , Milkha Singh
    
    • 1
  8. RavinderSingh13
    2024-11-17T23:42:00+08:002024-11-17T23:42:00+08:00

    Como meu Input_file é sempre o mesmo padrão, é sempre o mesmo, sem casos extremos, vou escrevê-lo desta maneira. Escrito e testado em GNU awk. Usando matchfunções com regex dentro delas e usando grupos de captura para armazenar valores em array nomeados arrque depois os imprimem conforme a necessidade.

    awk '
    match($0,/\(([^)]+)\) \(([^(]+)\([^)]+\))$/,arr){
      print arr[2]
      next
    }
    match($0,/^[^(]+\(([^(]+)\([^)]+\)\)$/,arr){
      print arr[1]
      next
    }
    match($0,/\(([^)]+)\)$/,arr){
      print arr[1]
      next
    }
    match($0,/\(([^(]+)\([^)]+\), ([^(]+)\(.*$/,arr){
      print arr[1] ", " arr[2]
    }
    '  Input_file
    

    A saída será a seguinte.

    bla bla1 
    Rinku Singh
    Rohit Sharma
    Virat kohli
    Ranbir kapoor , Milkha Singh
    
    • 1

relate perguntas

  • Como divido o loop for em 3 quadros de dados individuais?

  • Como verificar se todas as colunas flutuantes em um Pandas DataFrame são aproximadamente iguais ou próximas

  • Como funciona o "load_dataset", já que não está detectando arquivos de exemplo?

  • Por que a comparação de string pandas.eval() retorna False

  • Python tkinter/ ttkboostrap dateentry não funciona quando no estado somente leitura

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Vue 3: Erro na criação "Identificador esperado, mas encontrado 'import'" [duplicado]

    • 1 respostas
  • Marko Smith

    Por que esse código Java simples e pequeno roda 30x mais rápido em todas as JVMs Graal, mas não em nenhuma JVM Oracle?

    • 1 respostas
  • Marko Smith

    Qual é o propósito de `enum class` com um tipo subjacente especificado, mas sem enumeradores?

    • 1 respostas
  • Marko Smith

    Como faço para corrigir um erro MODULE_NOT_FOUND para um módulo que não importei manualmente?

    • 6 respostas
  • Marko Smith

    `(expression, lvalue) = rvalue` é uma atribuição válida em C ou C++? Por que alguns compiladores aceitam/rejeitam isso?

    • 3 respostas
  • Marko Smith

    Quando devo usar um std::inplace_vector em vez de um std::vector?

    • 3 respostas
  • Marko Smith

    Um programa vazio que não faz nada em C++ precisa de um heap de 204 KB, mas não em C

    • 1 respostas
  • Marko Smith

    PowerBI atualmente quebrado com BigQuery: problema de driver Simba com atualização do Windows

    • 2 respostas
  • Marko Smith

    AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos

    • 1 respostas
  • Marko Smith

    Estou tentando fazer o jogo pacman usando apenas o módulo Turtle Random e Math

    • 1 respostas
  • Martin Hope
    Aleksandr Dubinsky Por que a correspondência de padrões com o switch no InetAddress falha com 'não cobre todos os valores de entrada possíveis'? 2024-12-23 06:56:21 +0800 CST
  • Martin Hope
    Phillip Borge Por que esse código Java simples e pequeno roda 30x mais rápido em todas as JVMs Graal, mas não em nenhuma JVM Oracle? 2024-12-12 20:46:46 +0800 CST
  • Martin Hope
    Oodini Qual é o propósito de `enum class` com um tipo subjacente especificado, mas sem enumeradores? 2024-12-12 06:27:11 +0800 CST
  • Martin Hope
    sleeptightAnsiC `(expression, lvalue) = rvalue` é uma atribuição válida em C ou C++? Por que alguns compiladores aceitam/rejeitam isso? 2024-11-09 07:18:53 +0800 CST
  • Martin Hope
    The Mad Gamer Quando devo usar um std::inplace_vector em vez de um std::vector? 2024-10-29 23:01:00 +0800 CST
  • Martin Hope
    Chad Feller O ponto e vírgula agora é opcional em condicionais bash com [[ .. ]] na versão 5.2? 2024-10-21 05:50:33 +0800 CST
  • Martin Hope
    Wrench Por que um traço duplo (--) faz com que esta cláusula MariaDB seja avaliada como verdadeira? 2024-05-05 13:37:20 +0800 CST
  • Martin Hope
    Waket Zheng Por que `dict(id=1, **{'id': 2})` às vezes gera `KeyError: 'id'` em vez de um TypeError? 2024-05-04 14:19:19 +0800 CST
  • Martin Hope
    user924 AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos 2024-03-20 03:12:31 +0800 CST
  • Martin Hope
    MarkB Por que o GCC gera código que executa condicionalmente uma implementação SIMD? 2024-02-17 06:17:14 +0800 CST

Hot tag

python javascript c++ c# java typescript sql reactjs html

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve