Python 如何用正则表达式删除括号内的文本?
我正在尝试处理一堆文件,然后需要修改以删除文件名中的无关信息;值得注意的是,我试图删除括号内的文本。例如:Python 如何用正则表达式删除括号内的文本?,python,regex,perl,Python,Regex,Perl,我正在尝试处理一堆文件,然后需要修改以删除文件名中的无关信息;值得注意的是,我试图删除括号内的文本。例如: filename = "Example_file_(extra_descriptor).ext" 和我想重排一整组文件,括号中的表达式可能在中间或结尾,长度可变。 正则表达式是什么样子的?最好使用Perl或Python语法 s/\([^)]*\)// 因此,在Python中,您将执行以下操作: re.sub(r'\([^)]*\)', '', filename) 如果您可以使用sed
filename = "Example_file_(extra_descriptor).ext"
和我想重排一整组文件,括号中的表达式可能在中间或结尾,长度可变。
正则表达式是什么样子的?最好使用Perl或Python语法s/\([^)]*\)//
因此,在Python中,您将执行以下操作:
re.sub(r'\([^)]*\)', '', filename)
如果您可以使用
sed
(可能从您的程序中执行,它将非常简单:
sed 's/(.*)//g'
我将使用:
\([^)]*\)
如果路径可能包含括号,则
r'\(.*?\)
regex是不够的:
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'
如果您不一定需要使用正则表达式,可以考虑使用Perl删除括号
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;
}
你可能会想,“为什么一个正则表达式在一行中就完成了这一切?”
Text::Balanced处理嵌套括号。因此将正确提取$filename='foo_ubar(baz)buz)).foo'
。此处提供的基于正则表达式的解决方案将在此字符串上失败。一只会在第一次关门时停下来,另一只会把它们全吃掉
$filename =~ s/\([^}]*\)//;
# returns 'foo_buz)).foo'
$filename =~ s/\(.*\)//;
# returns 'foo_.foo'
# text balanced example returns 'foo_).foo'
如果任何一种正则表达式行为都是可以接受的,请使用正则表达式——但要记录所做的限制和假设。Java代码:
Pattern pattern1 = Pattern.compile("(\\_\\(.*?\\))");
System.out.println(fileName.replace(matcher1.group(1), ""));
匹配括号中没有其他
(
和)
字符的子字符串的模式是
详细信息:
-开口圆形支架(注意,在POSIX BRE中,\(
应使用,请参见下面的(
示例)sed
-零个或更多字符(由于[^()]*
)不是中定义的字符,即除*
和(
以外的任何字符)
-闭合圆括号(POSIX BRE中不允许逃逸)\)
- JavaScript:
string.replace(/\([^()]*\)/g',)
- PHP:
preg\u 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(“\\([^()]*\\),”)
- Ruby:
s.gsub(/\([^()]*\)/,“”)
- R:
gsub(\\([^()]*\\),“”,x)
- Lua:
string.gsub,“%([^()]*%”,“)
- Bash/sed:
sed的/([^()]*)///g'
- Tcl:
regsub-all{\([^()]*\)}$s”结果
- C++
:std::regex
std::regex\u替换(s,std::regex(R)(\([^()]*\))”,“”)
- Objective-C:
NSRegularExpression*regex=[NSRegularExpression regular expression with pattern:@“\\([^()]*\\)选项:NSRegularExpression不区分大小写错误:&error]; NSString*modifiedString=[regex StringByReplacingMatcheInstalling:string选项:0范围:NSMakeRange(0,[string length]),带模板:@”“];
- Swift:
s.replacingOccurrences(of:“\\([^()]*\\)”,with:,options:[.regularExpression])
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')
您只是将表达式
*
@Gumbo:不,他不是。在sed中,“\(…\)”groups.Ops,对不起。我不知道。有什么理由更喜欢。*?而不是[^)]*@Kip:nope。我不知道为什么,但是。*始终是我想到的第一件事。@Kip:.*不是由所有正则表达式分析器处理的,而您的[^]*几乎所有人都在处理。@Kip:另一个原因是回溯。*获取第一个左参数和最后一个右参数之间的所有内容:“a(b)c(d)e”将变为“ae”。[^)]*仅在第一个左参数和第一个右参数之间删除:“ac(d)e”。嵌套参数也会有不同的行为。虽然我知道不能用(经典)正则表达式解析嵌套括号,但如果知道永远不会遇到嵌套括号,可以将问题简化为可以用正则表达式完成的问题,而且相当容易。当我们不需要解析器工具时,使用它太过分了。@Chris Lutz-我应该在第一句中说“考虑”而不是“使用”。在很多情况下,正则表达式会起作用,这就是为什么我说如果行为可以接受,就使用正则表达式。你确定“额外描述符”不能包含“)”?如果可以的话,问题就变得更难了…@dmckee:如果paren可以嵌套就更难了,不过如果你只是想去掉第一个“(“和最后一个“)”之间的所有东西,那就不难了。只要用贪婪的“*”而不是“*?”。@j_random_hacker你是对的,这要困难得多,因为嵌套括号不能被FSM识别(你必须跟踪嵌套级别,它是无限的),因此不能被正则表达式识别。为了使其成为可能,您必须将自己限制在有限的嵌套级别。我已经想自己编写嵌套方括号删除程序,但您节省了我的时间,谢谢!
Pattern pattern1 = Pattern.compile("(\\_\\(.*?\\))");
System.out.println(fileName.replace(matcher1.group(1), ""));
\([^()]*\)
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')