Как я могу удалить текст в скобках с помощью регулярного выражения? - PullRequest
57 голосов
/ 12 марта 2009

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

filename = "Example_file_(extra_descriptor).ext"

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

Как бы выглядело регулярное выражение? Предпочтителен синтаксис Perl или Python.

Ответы [ 9 ]

91 голосов
/ 12 марта 2009
s/\([^)]*\)//

Итак, в Python вы должны сделать:

re.sub(r'\([^)]*\)', '', filename)
28 голосов
/ 16 ноября 2016

Шаблон, соответствующий подстрокам в скобках , не содержащий других символов ( и ) между (например, (xyz 123) в Text (abc(xyz 123)), равен

\([^()]*\)

Подробнее :

Удаление фрагментов кода:

  • JavaScript : string.replace(/\([^()]*\)/g, '')
  • PHP : preg_replace('~\([^()]*\)~', '', $string)
  • Perl : $s =~ s/\([^()]*\)//g
  • Python : re.sub(r'\([^()]*\)', '', s)
  • C # : Regex.Replace(str, @"\([^()]*\)", string.Empty)
  • VB.NET : Regex.Replace(str, "\([^()]*\)", "")
  • Java : s.replaceAll("\\([^()]*\\)", "")
  • Рубин : s.gsub(/\([^()]*\)/, '')
  • R : gsub("\\([^()]*\\)", "", x)
  • Луа : string.gsub(s, "%([^()]*%)", "")
  • Баш / сед : sed 's/([^()]*)//g'
  • Tcl : regsub -all {\([^()]*\)} $s "" result
  • C ++ std::regex: std::regex_replace(s, std::regex(R"(\([^()]*\))"), "")
  • Объектив-C :
    NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"\\([^()]*\\)" options:NSRegularExpressionCaseInsensitive error:&error]; NSString *modifiedString = [regex stringByReplacingMatchesInString:string options:0 range:NSMakeRange(0, [string length]) withTemplate:@""];
  • Swift : s.replacingOccurrences(of: "\\([^()]*\\)", with: "", options: [.regularExpression])
21 голосов
/ 12 марта 2009

Я бы использовал:

\([^)]*\)
6 голосов
/ 13 марта 2009

Если вам абсолютно не нужно использовать регулярное выражение, используйте и рассмотрите возможность использования Perl's Text :: Balanced для удаления скобок.

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;
}

Возможно, вы думаете: «Зачем все это, когда регулярное выражение выполняет трюк в одной строке?»

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

Text :: Balanced обрабатывает вложенные скобки. Так что $filename = 'foo_(bar(baz)buz)).foo' будет извлечен правильно. Предлагаемые здесь решения на основе регулярных выражений потерпят неудачу в этой строке. Один остановится на первом закрытии, другой съест их всех.

$ filename = ~ s / ([^}] *) //; # возвращает 'foo_buz)). foo'

$ filename = ~ s /(.*)//; # возвращает 'foo_.foo'

# сбалансированный текстовый пример возвращает 'foo _). Foo'

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

2 голосов
/ 15 декабря 2017

Для тех, кто хочет использовать Python, вот простая процедура, которая удаляет заключенные в скобки подстроки, в том числе с вложенными скобками. Хорошо, это не регулярное выражение, но оно сработает!

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 голосов
/ 12 марта 2009

Если путь может содержать круглые скобки, то регулярного выражения r'\(.*?\)' недостаточно:

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)

По умолчанию функция сохраняет куски в скобках в каталоге и в расширенных частях пути.

Пример:

>>> 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 голосов
/ 12 марта 2009

Если вы можете использовать sed (возможно, выполнить изнутри вашей программы, это будет так просто:

sed 's/(.*)//g'
0 голосов
/ 03 августа 2012

Java-код:

Pattern pattern1 = Pattern.compile("(\\_\\(.*?\\))");
System.out.println(fileName.replace(matcher1.group(1), ""));
0 голосов
/ 13 марта 2009
>>> import re
>>> filename = "Example_file_(extra_descriptor).ext"
>>> p = re.compile(r'\([^)]*\)')
>>> re.sub(p, '', filename)
'Example_file_.ext'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...