我需要一個正則表達式來選擇兩個外括號之間的所有文本。正則表達式匹配外括號
例子:some text(text here(possible text)text(possible text(more text)))end text
結果:(text here(possible text)text(possible text(more text)))
我一直在嘗試了幾個小時,你要知道我的正則表達式的知識是不是我想它是:-)所以任何幫助會感激地收到。
我需要一個正則表達式來選擇兩個外括號之間的所有文本。正則表達式匹配外括號
例子:some text(text here(possible text)text(possible text(more text)))end text
結果:(text here(possible text)text(possible text(more text)))
我一直在嘗試了幾個小時,你要知道我的正則表達式的知識是不是我想它是:-)所以任何幫助會感激地收到。
正則表達式是工作的錯誤工具,因爲您正在處理嵌套結構,即遞歸。
但有一個簡單的算法來做到這一點,我把in this answer描述爲previous question。
[^\(]*(\(.*\))[^\)]*
[^\(]*
匹配一切不是在字符串的開始處的開口支架,(\(.*\))
捕獲括在括號內的所需的子串,並[^\)]*
在字符串的末尾匹配的一切,是不是一個結束括號。請注意,此表達式不會嘗試匹配括號;一個簡單的解析器(見dehmann's answer)會更適合這個。
類裏面的支架做不需要逃脫。由於裏面它不是一個metacharacted。 – 2009-02-13 15:59:05
這個expr失敗了,例如「文本(文本)文本(文本)文本」返回「(文本)文本(文本)」。正則表達式不能計算括號。 – 2009-02-13 16:02:13
(?<=\().*(?=\))
如果你想兩個匹配括號之間選擇文本,你的運氣了正則表達式。這是不可能的(*)。
這個正則表達式只是返回字符串中第一個開頭和最後一個關閉括號之間的文本。
(*)除非你的正則表達式引擎有一個像balancing groups or recursion功能。支持這些功能的引擎數量正在慢慢增長,但它們仍然不是常用的。
「<=」和「=」符號是什麼意思?這種表達式定位的是什麼正則表達式引擎? – 2009-02-13 15:58:38
這是環視或更正確的「零寬度預見/後顧斷言」。大多數現代正則表達式引擎都支持它們。 – Tomalak 2009-02-13 16:01:21
根據OP的例子,他想在比賽中包括最外面的人。這個正則表達式會把它們扔掉。 – 2009-02-15 05:09:06
這是明確的正則表達式:
\(
(?<arguments>
(
([^\(\)']*) |
(\([^\(\)']*\)) |
'(.*?)'
)*
)
\)
例子:
input: (arg1, arg2, arg3, (arg4), '(pip')
output: arg1, arg2, arg3, (arg4), '(pip'
注意,'(pip'
正確的字符串管理。
使用Ruby正則表達式(1.9.3或以上版本): (http://sourceforge.net/projects/regulator/在調節器試過):
/(?<match>\((?:\g<match>|[^()]++)*\))/
可以使用regex recursion:
\(([^()]|(?R))*\)
我想添加這個答案quickreference。隨時更新。
.NET正則表達式使用balancing groups。
\((?>\((?<c>)|[^()]+|\)(?<-c>))*(?(c)(?!))\)
其中c
被用作深度計數器。
PCRE。
\((?>[^)(]+|(?R))*\)
Demo at regex101;或者沒有改變:
\((?>[^)(]*(?R)?)*\)
Demo at regex101。該圖案粘貼在代表(?0)
的(?R)
。
的Perl,PHP,記事本++,- [R:perl=TRUE,的Python:Regex package與(?V1)
爲Perl行爲。
使用subexpression calls紅寶石。
用Ruby 2.0 \g<0>
可以用來調用全模式。
\((?>[^)(]+|\g<0>)*\)
Demo at Rubular; Ruby 1.9的只支持capturing group recursion:
(\((?>[^)(]+|\g<1>)*\))
Demo at Rubular (atomic grouping因爲紅寶石1.9.3)
的JavaScript API :: XRegExp.matchRecursive
XRegExp.matchRecursive(str, '\\(', '\\)', 'g');
JS,Java和其他正則表達式的口味,而不遞歸最多2級o f嵌套:
\((?:[^)(]+|\((?:[^)(]+|\([^)(]*\))*\))*\)
Demo at regex101。更深的nesting needs to be added模式。
要失敗快上不平衡括號drop the +
quantifier.
的Java:一個有趣的idea using forward references by @jaytea。
這裏是一個定製的解決方案,允許單個字符文字分隔符在Java中:
public static List<String> getBalancedSubstrings(String s, Character markStart,
Character markEnd, Boolean includeMarkers)
{
List<String> subTreeList = new ArrayList<String>();
int level = 0;
int lastOpenDelimiter = -1;
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (c == markStart) {
level++;
if (level == 1) {
lastOpenDelimiter = (includeMarkers ? i : i + 1);
}
}
else if (c == markEnd) {
if (level == 1) {
subTreeList.add(s.substring(lastOpenDelimiter, (includeMarkers ? i + 1 : i)));
}
if (level > 0) level--;
}
}
return subTreeList;
}
}
使用範例:
String s = "some text(text here(possible text)text(possible text(more text)))end text";
List<String> balanced = getBalancedSubstrings(s, '(', ')', true);
System.out.println("Balanced substrings:\n" + balanced);
// => [(text here(possible text)text(possible text(more text)))]
所以你需要第一個和最後parenthess,使用不便這樣 str.indexOf( '('); - 它會給你第一次發生 str.lastIndexOf(')'); - 最後一個
所以你需要字符串, String searchingString = str.substring(str1.indexOf('('),str1。lastIndexOf( ')');
"""
Here is a simple python program showing how to use regular
expressions to write a paren-matching recursive parser.
This parser recognises items enclosed by parens, brackets,
braces and <> symbols, but is adaptable to any set of
open/close patterns. This is where the re package greatly
assists in parsing.
"""
import re
# The pattern below recognises a sequence consisting of:
# 1. Any characters not in the set of open/close strings.
# 2. One of the open/close strings.
# 3. The remainder of the string.
#
# There is no reason the opening pattern can't be the
# same as the closing pattern, so quoted strings can
# be included. However quotes are not ignored inside
# quotes. More logic is needed for that....
pat = re.compile("""
(.*?)
(\(| \) | \[ | \] | \{ | \} | \< | \> |
\' | \" | BEGIN | END | $)
(.*)
""", re.X)
# The keys to the dictionary below are the opening strings,
# and the values are the corresponding closing strings.
# For example "(" is an opening string and ")" is its
# closing string.
matching = { "(" : ")",
"[" : "]",
"{" : "}",
"<" : ">",
'"' : '"',
"'" : "'",
"BEGIN" : "END" }
# The procedure below matches string s and returns a
# recursive list matching the nesting of the open/close
# patterns in s.
def matchnested(s, term=""):
lst = []
while True:
m = pat.match(s)
if m.group(1) != "":
lst.append(m.group(1))
if m.group(2) == term:
return lst, m.group(3)
if m.group(2) in matching:
item, s = matchnested(m.group(3), matching[m.group(2)])
lst.append(m.group(2))
lst.append(item)
lst.append(matching[m.group(2)])
else:
raise ValueError("After <<%s %s>> expected %s not %s" %
(lst, s, term, m.group(2)))
# Unit test.
if __name__ == "__main__":
for s in ("simple string",
""" "double quote" """,
""" 'single quote' """,
"one'two'three'four'five'six'seven",
"one(two(three(four)five)six)seven",
"one(two(three)four)five(six(seven)eight)nine",
"one(two)three[four]five{six}seven<eight>nine",
"one(two[three{four<five>six}seven]eight)nine",
"oneBEGINtwo(threeBEGINfourENDfive)sixENDseven",
"ERROR testing (((mismatched))] parens"):
print "\ninput", s
try:
lst, s = matchnested(s)
print "output", lst
except ValueError as e:
print str(e)
print "done"
正則表達式不能這樣做。
正則表達式基於被稱爲Finite State Automata (FSA)
的計算模型。正如名稱所示,FSA
只能記住當前狀態,它沒有關於以前狀態的信息。
在上述圖中,S1和S2是兩種狀態,其中S1是起始和最終步驟。因此,如果我們用字符串0110
嘗試,轉型去如下:
0 1 1 0
-> S1 -> S2 -> S2 -> S2 ->S1
在上面的步驟,當我們正處於第二S2
即解析的0110
01
之後,FSA沒有關於以前0
信息在01
,因爲它只能記住當前狀態和下一個輸入符號。
在上面的問題中,我們需要知道左括號的否;這意味着它必須在存儲在某個地方。但由於FSAs
不能這樣做,所以不能寫正則表達式。
但是,可以編寫一個算法來實現目標。算法通常屬於Pushdown Automata (PDA)
。 PDA
比FSA
高一級。 PDA有一個額外的堆棧來存儲一些東西。 PDA可以用來解決上述問題,因爲我們可以'push
'堆棧中的左括號和'pop
'他們一旦我們遇到一個右括號。如果最後堆棧爲空,則打開括號和右括號匹配。否則不是。
的詳細討論可以發現here。
這個問題很差,因爲它不清楚它在問什麼。所有的答案都以不同的方式解釋。 @DaveF你能否澄清這個問題? – 2012-12-17 18:25:17
回答這個帖子: http://stackoverflow.com/questions/6331065/matching-balanced-parenthesis-in-ruby-using-recursive-regular-expressions-like-p – sship21 2013-12-06 22:47:59