web-dev-qa-db-fra.com

Comment puis-je supprimer du texte entre parenthèses avec une expression rationnelle?

J'essaie de gérer un tas de fichiers et je dois ensuite modifier pour supprimer les informations superflues dans les noms de fichiers; notamment, j'essaie de supprimer du texte entre parenthèses. Par exemple:

filename = "Example_file_(extra_descriptor).ext"

et je veux parler d'un tas de fichiers où l'expression entre parenthèses peut être au milieu ou à la fin, et de longueur variable.

À quoi ressemblerait la regex? La syntaxe Perl ou Python serait préférable.

51
Technical Bard
s/\([^)]*\)//

Donc, en Python, vous feriez:

re.sub(r'\([^)]*\)', '', filename)
85
Can Berk Güder

J'utiliserais:

\([^)]*\)
20
Gumbo

Si vous n'avez absolument pas besoin d'utiliser un regex, utilisationpensez à utiliser Perl's Text :: Balanced pour supprimer la parenthèse.

use Text::Balanced qw(extract_bracketed);

my ($extracted, $remainder, $prefix) = extract_bracketed( $filename, '()', '[^(]*' );

{   no warnings 'uninitialized';

    $filename = (defined $prefix or defined $remainder)
                ? $prefix . $remainder
                : $extracted;
}

Vous pensez peut-être, "Pourquoi faire tout cela quand une expression rationnelle fait le tour en une ligne?"

$filename =~ s/\([^}]*\)//;

Text :: Balanced gère les parenthèses imbriquées. Donc, $filename = 'foo_(bar(baz)buz)).foo' sera extrait correctement. Les solutions basées sur les expressions régulières proposées ici échoueront sur cette chaîne. L'un s'arrêtera à la première heure de clôture et l'autre les mangera tous.

$ nom_fichier = ~ s /((^^******* # renvoie 'foo_buz)). foo'

$ filename = ~ s /(.*)//; # renvoie 'foo_.foo'

# texte équilibré par exemple retourne 'foo _). foo'

Si l'un ou l'autre des comportements de regex est acceptable, utilisez une regex, mais expliquez les limites et les hypothèses.

6
daotoad

Pour ceux qui souhaitent utiliser Python, voici une routine simple qui supprime les sous-chaînes entre parenthèses, y compris celles comportant des parenthèses imbriquées. D'accord, ce n'est pas une regex, mais ça fera le travail!

def remove_nested_parens(input_str):
    """Returns a copy of 'input_str' with any parenthesized text removed. Nested parentheses are handled."""
    result = ''
    paren_level = 0
    for ch in input_str:
        if ch == '(':
            paren_level += 1
        Elif (ch == ')') and paren_level:
            paren_level -= 1
        Elif not paren_level:
            result += ch
    return result

remove_nested_parens('example_(extra(qualifier)_text)_test(more_parens).ext')
2
Andrew Basile

Si vous pouvez supporter d'utiliser sed (éventuellement exécuter à partir de votre programme, ce serait aussi simple que:

sed 's/(.*)//g'
2
samoz

Si un chemin peut contenir des parenthèses, la regex r'\(.*?\)' ne suffit pas:

import os, re

def remove_parenthesized_chunks(path, safeext=True, safedir=True):
    dirpath, basename = os.path.split(path) if safedir else ('', path)
    name, ext = os.path.splitext(basename) if safeext else (basename, '')
    name = re.sub(r'\(.*?\)', '', name)
    return os.path.join(dirpath, name+ext)

Par défaut, la fonction conserve les fragments entre parenthèses dans les parties répertoire et extension du chemin.

Exemple:

>>> f = remove_parenthesized_chunks
>>> f("Example_file_(extra_descriptor).ext")
'Example_file_.ext'
>>> path = r"c:\dir_(important)\example(extra).ext(untouchable)"
>>> f(path)
'c:\\dir_(important)\\example.ext(untouchable)'
>>> f(path, safeext=False)
'c:\\dir_(important)\\example.ext'
>>> f(path, safedir=False)
'c:\\dir_\\example.ext(untouchable)'
>>> f(path, False, False)
'c:\\dir_\\example.ext'
>>> f(r"c:\(extra)\example(extra).ext", safedir=False)
'c:\\\\example.ext'
2
jfs
>>> import re
>>> filename = "Example_file_(extra_descriptor).ext"
>>> p = re.compile(r'\([^)]*\)')
>>> re.sub(p, '', filename)
'Example_file_.ext'
0
riza

Code Java:

Pattern pattern1 = Pattern.compile("(\\_\\(.*?\\))");
System.out.println(fileName.replace(matcher1.group(1), ""));
0
Peer Mohamed