Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/google-cloud-platform/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex 匹配平衡圆括号的正则表达式_Regex - Fatal编程技术网

Regex 匹配平衡圆括号的正则表达式

Regex 匹配平衡圆括号的正则表达式,regex,Regex,我需要一个正则表达式来选择两个外括号之间的所有文本 示例:一些文本(此处的文本(可能文本)文本(可能文本(更多文本)))结束文本 [^\(]*(\(.*\))[^\)]* 结果:(此处文本(可能文本)文本(可能文本(更多文本)) [^\(]*匹配字符串开头处不是左括号的所有内容,(\(.*)捕获括号中包含的所需子字符串,[^\)]*匹配字符串结尾处不是右括号的所有内容。请注意,此表达式不尝试匹配括号;一个简单的解析器(请参阅)更适合于此 (?正则表达式对于该作业来说是错误的工具,因为您处理的是

我需要一个正则表达式来选择两个外括号之间的所有文本

示例:
一些文本(此处的文本(可能文本)文本(可能文本(更多文本)))结束文本

[^\(]*(\(.*\))[^\)]*
结果:
(此处文本(可能文本)文本(可能文本(更多文本))


[^\(]*
匹配字符串开头处不是左括号的所有内容,
(\(.*)
捕获括号中包含的所需子字符串,
[^\)]*
匹配字符串结尾处不是右括号的所有内容。请注意,此表达式不尝试匹配括号;一个简单的解析器(请参阅)更适合于此

(?正则表达式对于该作业来说是错误的工具,因为您处理的是嵌套结构,即递归

(?<=\().*(?=\))

但是有一个简单的算法可以做到这一点,我对a进行了更详细的描述。要点是编写代码,扫描字符串,保留一个开括号的计数器,该计数器尚未与右括号匹配。当该计数器返回到零时,您就知道已到达最后的右括号。

答案取决于是否需要匹配括号的匹配集,或者只需要匹配输入文本中从第一个打开到最后一个关闭的部分

\s*\w+[(][^+]*[)]\s*
如果您需要匹配嵌套括号,那么您需要的不仅仅是正则表达式。-请参阅

如果只是从第一次打开到最后一次关闭,请参见

决定您希望发生的事情:

abc ( 123 ( foobar ) def ) xyz ) ghij

在这种情况下,您需要确定代码需要匹配的内容。

实际上可以使用.NET正则表达式进行匹配,但这并不是一件小事,所以请仔细阅读

你可以读一篇好文章。你可能还需要阅读.NET正则表达式。你可以开始阅读了

之所以使用尖括号
,是因为它们不需要转义

正则表达式如下所示:

<
[^<>]*
(
    (
        (?<Open><)
        [^<>]*
    )+
    (
        (?<Close-Open>>)
        [^<>]*
    )+
)*
(?(Open)(?!))
>
<
[^]*
(
(
(?)
[^]*
)+
)*
(?(开放)(?!))
>

这是最终的正则表达式:

\(
(?<arguments> 
(  
  ([^\(\)']*) |  
  (\([^\(\)']*\)) |
  '(.*?)'

)*
)
\)
请注意,
”(pip'
作为字符串正确管理。
(在调节器中试用:)

使用Ruby(1.9.3或更高版本)的正则表达式:

/(?\(?:\g|[^()]++)*\)/
您可以使用:


我编写了一个小JavaScript库来帮助完成这项任务

balanced.matches({
    source: source,
    open: '(',
    close: ')'
});
您甚至可以进行替换:

balanced.replacements({
    source: source,
    open: '(',
    close: ')',
    replace: function (source, head, tail) {
        return head + source + tail;
    }
});

这里有一个更复杂、更具交互性的示例。

我想添加此答案以供快速参考。请随时更新


.NET Regex使用

;或不作改动:

\((?:[^)(]*(?R)?)*+\)
;或就表现而言:

\([^)(]*+(?:(?R)[^)(]*)*+\)
;图案粘贴在
(?R)
处,表示
(?0)

Perl,PHP,Notepad++,R:,Python:with
(?V1)
用于Perl行为


Ruby使用

使用Ruby 2.0,可以使用
\g
调用完整模式

\((?>[^)(]+|\g<0>)*\)
JS、Java和其他正则表达式风格,无递归,最多可嵌套两级:

\((?:[^)(]+|\((?:[^)(]+|\([^)(]*\))*\))*\)
.深入到模式。
在不平衡括号上更快地失败


Java:一个有趣的例子



除此之外,还有其他支持递归构造的正则表达式

Lua

使用
%b()
%b{}
/
%b[]
表示大括号/方括号):

  • 用于字符串中的s.gmatch(“提取(a(b)c)和((d)f(g)),“%b()”)是否打印结束
    (请参阅)
拉库(前Perl6)

不重叠的多个平衡圆括号匹配:

my regex paren_any { '(' ~ ')' [ <-[()]>+ || <&paren_any> ]* }
say "Extract (a(b)c) and ((d)f(g))" ~~ m:g/<&paren_any>/;
# => (「(a(b)c)」 「((d)f(g))」)
say "Extract (a(b)c) and ((d)f(g))" ~~ m:ov:g/<&paren_any>/;
# => (「(a(b)c)」 「(b)」 「((d)f(g))」 「(d)」 「(g)」)
示例用法:

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)))]
String s=“一些文本(此处文本(可能文本)文本(可能文本(更多文本)))结束文本”;
List balanced=getBalancedSubstrings,“(”,“)”,true;
System.out.println(“平衡子字符串:\n”+平衡);
//=>[(此处文本(可能文本)文本(可能文本(更多文本)))]

您需要第一个和最后一个括号。请使用以下内容:

<
[^<>]*
(
    (
        (?<Open><)
        [^<>]*
    )+
    (
        (?<Close-Open>>)
        [^<>]*
    )+
)*
(?(Open)(?!))
>
str.indexOf(“(”);-它将给您第一次出现

str.lastIndexOf(');-最后一个

所以你需要一条线

String searchedString = str.substring(str1.indexOf('('),str1.lastIndexOf(')');
“”“
下面是一个简单的python程序,演示如何使用正则表达式
表达式来编写paren匹配递归解析器。
此解析器识别由括号、括号和,
大括号和符号,但适用于任何一组
打开/关闭模式。这是重新打包的地方
协助解析。
"""
进口稀土
#下面的模式识别一个序列,该序列包括:
#1.不在打开/关闭字符串集中的任何字符。
#2.打开/关闭字符串之一。
#3.字符串的其余部分。
# 
#没有理由不让开场模式成为最佳模式
#与结束模式相同,因此带引号的字符串可以
#被包括在内。但是引用在里面不会被忽略
#引用。这需要更多的逻辑。。。。
pat=re.compile(“”)
( .*? )
( \( | \) | \[ | \] | \{ | \} | \< | \> |
\“|\”|开始|结束|$)
( .* )
“”,re.X)
#下面字典的键是开头的字符串,
#这些值是相应的结束字符串。
#例如,“(”是一个开头字符串,“)”是它的
#结束字符串。
匹配={“(“:”),
"[" : "]",
"{" : "}",
"",
'"' : '"',
"'" : "'",
“开始”:“结束”}
#下面的过程匹配字符串s并返回
#与打开/关闭的嵌套匹配的递归列表
#美国的模式。
def matchnested(s,term=”“):
lst=[]
尽管如此:
m=匹配匹配(s)
如果m.group(1)!=“”:
一级附加(m组(1))
如果m.群(2)=项:
返回lst,m.组(3)
如果m.group(2)处于匹配状态:
项目,s=匹配嵌套(m.group(3),匹配[m.group(2)])
一级附加(m组(2))
第一个附加项(项目)
\((?:[^)(]+|\((?:[^)(]+|\([^)(]*\))*\))*\)
my regex paren_any { '(' ~ ')' [ <-[()]>+ || <&paren_any> ]* }
say "Extract (a(b)c) and ((d)f(g))" ~~ m:g/<&paren_any>/;
# => (「(a(b)c)」 「((d)f(g))」)
say "Extract (a(b)c) and ((d)f(g))" ~~ m:ov:g/<&paren_any>/;
# => (「(a(b)c)」 「(b)」 「((d)f(g))」 「(d)」 「(g)」)
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)))]
String searchedString = 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"
      0     1     1     0
-> S1 -> S2 -> S2 -> S2 ->S1
re.findall(r'\(.+\)', s)
push(number) map(test(a(a()))) bass(wow, abc)
$$(groups) filter({ type: 'ORGANIZATION', isDisabled: { $ne: true } }) pickBy(_id, type) map(test()) as(groups)
const parser = str => {
  let ops = []
  let method, arg
  let isMethod = true
  let open = []

  for (const char of str) {
    // skip whitespace
    if (char === ' ') continue

    // append method or arg string
    if (char !== '(' && char !== ')') {
      if (isMethod) {
        (method ? (method += char) : (method = char))
      } else {
        (arg ? (arg += char) : (arg = char))
      }
    }

    if (char === '(') {
      // nested parenthesis should be a part of arg
      if (!isMethod) arg += char
      isMethod = false
      open.push(char)
    } else if (char === ')') {
      open.pop()
      // check end of arg
      if (open.length < 1) {
        isMethod = true
        ops.push({ method, arg })
        method = arg = undefined
      } else {
        arg += char
      }
    }
  }

  return ops
}

// const test = parser(`$$(groups) filter({ type: 'ORGANIZATION', isDisabled: { $ne: true } }) pickBy(_id, type) map(test()) as(groups)`)
const test = parser(`push(number) map(test(a(a()))) bass(wow, abc)`)

console.log(test)

[ { method: 'push', arg: 'number' },
  { method: 'map', arg: 'test(a(a()))' },
  { method: 'bass', arg: 'wow,abc' } ]
[ { method: '$$', arg: 'groups' },
  { method: 'filter',
    arg: '{type:\'ORGANIZATION\',isDisabled:{$ne:true}}' },
  { method: 'pickBy', arg: '_id,type' },
  { method: 'map', arg: 'test()' },
  { method: 'as', arg: 'groups' } ]
def extract_code(data):
    """ returns an array of code snippets from a string (data)"""
    start_pos = None
    end_pos = None
    count_open = 0
    count_close = 0
    code_snippets = []
    for i,v in enumerate(data):
        if v =='{':
            count_open+=1
            if not start_pos:
                start_pos= i
        if v=='}':
            count_close +=1
            if count_open == count_close and not end_pos:
                end_pos = i+1
        if start_pos and end_pos:
            code_snippets.append((start_pos,end_pos))
            start_pos = None
            end_pos = None

    return code_snippets

'/(\((?>[^()]+|(?1))*\))/'
\s*\w+[(][^+]*[)]\s*