如何提取最外层括号间的文本?求正则表达式或脚本代码
Got it, extracting the outermost paired parentheses that contain nested inner parentheses is a common problem—basic regex can't handle this out of the box because most default regex engines don't track nesting levels. Here are practical solutions depending on your tooling:
1. Regex (for engines supporting recursive/balanced groups)
If you're using a regex flavor that supports recursion (like .NET, or Python's regex third-party library), you can use a pattern that matches balanced parentheses:
\((?>[^()]+|(?R))*\)
Breakdown of the pattern:
\(: Matches the opening outer parenthesis(?>...): An atomic group to prevent unnecessary backtracking[^()]+: Matches any sequence of characters that aren't parentheses(?R): Recursively matches the entire regex pattern (handles nested parentheses)*\): Matches the closing outer parenthesis after all nested content is processed
Example usage in Python (with regex library):
First install the library if you haven't: pip install regex
import regex text1 = "some text(text here(possible text)text(possible text(more text)))end text" match = regex.search(r"\((?>[^()]+|(?R))*\)", text1) if match: print(match.group()) # Output: (text here(possible text)text(possible text(more text)))
2. Script-Based Solution (Works in All Languages)
If regex recursion isn't available, a simple script that tracks parenthesis depth is more reliable. Here are implementations in two common languages:
Python (Standard Library Only)
def extract_outer_parentheses(text): start_idx = None depth = 0 for idx, char in enumerate(text): if char == '(': if depth == 0: start_idx = idx depth += 1 elif char == ')': depth -= 1 if depth == 0 and start_idx is not None: return text[start_idx:idx+1] return None # Returns None if no complete outer pair is found # Test with your first example sample1 = "some text(text here(possible text)text(possible text(more text)))end text" print(extract_outer_parentheses(sample1)) # To extract ALL outer parentheses pairs (like your second example) def extract_all_outer_parentheses(text): results = [] start_idx = None depth = 0 for idx, char in enumerate(text): if char == '(': if depth == 0: start_idx = idx depth += 1 elif char == ')': depth -= 1 if depth == 0 and start_idx is not None: results.append(text[start_idx:idx+1]) start_idx = None return results sample2 = "(Jack Tomy)(Smith)(ti,ab(((Abbott near/10 (assay* OR test* OR analy* OR array )) OR (Abbott p/1 Point P/1 Care) OR ARCHITECT OR (CELL p/0 DYN)) OR ((Alere near/10 (assay* OR test* OR analy* OR ar..." print(extract_all_outer_parentheses(sample2))
JavaScript
// Extract the first outer parentheses pair function extractOuterParentheses(text) { let startIdx = null; let depth = 0; for (let i = 0; i < text.length; i++) { const char = text[i]; if (char === '(') { if (depth === 0) startIdx = i; depth++; } else if (char === ')') { depth--; if (depth === 0 && startIdx !== null) { return text.slice(startIdx, i + 1); } } } return null; } // Extract all outer parentheses pairs function extractAllOuterParentheses(text) { const results = []; let startIdx = null; let depth = 0; for (let i = 0; i < text.length; i++) { const char = text[i]; if (char === '(') { if (depth === 0) startIdx = i; depth++; } else if (char === ')') { depth--; if (depth === 0 && startIdx !== null) { results.push(text.slice(startIdx, i + 1)); startIdx = null; } } } return results; } // Test your examples const sample1 = "some text(text here(possible text)text(possible text(more text)))end text"; console.log(extractOuterParentheses(sample1)); const sample2 = "(Jack Tomy)(Smith)(ti,ab(((Abbott near/10 (assay* OR test* OR analy* OR array )) OR (Abbott p/1 Point P/1 Care) OR ARCHITECT OR (CELL p/0 DYN)) OR ((Alere near/10 (assay* OR test* OR analy* OR ar..."; console.log(extractAllOuterParentheses(sample2));
Why This Works
The script tracks the depth of parentheses: every time it hits an opening (, it increases the depth, and every closing ) decreases it. When the depth returns to 0, we know we've found the matching outer closing parenthesis.
内容的提问来源于stack exchange,提问作者MokiNex

