我试图创建一个正则表达式模式来匹配每个(内容*),但是该模式可以在另一个((内容)(内容))中找到。我尝试了"\((. *?) \)"
,但这返回了外部的。
例如:字符串('fdmg')(R: Percentual('dmg')(20))
应返回:
第一个匹配:fdmg
第二个匹配:R:Percentual('dmg')(20)
编辑:
我试过:\((?:[0-9A-Z-a-Z':]|(?R))*\)
但在?R(未知标志)附近出现错误
如果你只想要2级嵌套,如问题中所示,而不是更深层次的递归,那么你可以用正面的lookaheads来实现。
正则表达式:(?=(\([^()]*(?:\([^()]*\)[^()]*)*\)
参见regex101.com演示。
结果(第1组*)
('fdmg')
(R:Percentual ('dmg') (20))
('dmg')
(20)
*)组0始终是空字符串
我知道这是一个与RegEx有关的问题,但我想我会把这个放在这里。
就我个人而言,我不会试图让正则表达式获得一个特定的嵌套括号深度,即使您试图获得的深度仅为1。下面是两种方法,它们可以在括号类型的任意深度检索所需的括号子字符串:(
,[]
,{}
,和
/**
* This method will parse out (retrieve) the contents of nested brackets
* groups within a bracketed string and return those group contents within a
* Single Dimensional String Array. The best way to see how this works is by
* examples. Let's say we have the following bracketed string:<pre>
*
* String a = "1(2(3)(4))(5(6)(7))";</pre><br>
*
* In the above string we can see that there are two instances of level 1
* bracketed groups which in each level 1 group nest two more level 2
* bracketed groups:
* <pre>
*
* Level 1 Level 2
* (2(3)(4)) (3) (4)
*
* ==================================
*
* Level 1 Level 2
* (5(6)(7)) (6) (7)</pre><br>
*
* Bracketed groups: <b>(2(3)(4))</b> and <b>(5(6)(7))</b> are both
* considered to be at nest level 1 (level 1 is the outer most level). They
* are both individual groups because they both have their own set of outer
* brackets. Within each level 1 group we have two sets of level 2 bracketed
* groups (4 level 2 groups altogether) which consist of: <b>(3)</b> &
* <b>(4)</b> and <b>(6)</b> & <b>
* (7)</b>.<br><br>
*
* This method also utilizes the bracketsMaxDepth() method.
*
* @param bracketedString (String) The string which contains bracketed
* content to parse.<br>
*
* @param desiredDepth (Integer) Default is 0 (full depth). The
* nested depth to retrieve bracketed content
* from.<br> If the bracket depth supplied is
* deeper than what is contained within the
* supplied input string then an <b>IllegalArgu-
* mentException</b> is thrown explaining as
* such.
*
* @param bracketType (String) You must supply the bracket type to
* process or null to use the default bracket
* type of parentheses ("()"). You can provide
* the bracket type to work against by supplying
* either a single open or close bracket or both
* open and close brackets, for example, any one
* of the following are all acceptable entries if
* parentheses are required:<pre>
*
* "(" ")" "()" ")("</pre><br>
*
* Any one of four (4) bracket types can be supplied. The allowable Bracket
* Types are:<pre>
*
* () Parentheses
* {} Curly Braces
* [] Square Brackets
* <> Chevron Brackets</pre>
*
* @param removeOuterBrackets (Optional - Boolean - Default is false) By
* default the outer brackets for each found
* group are also attached to the returned
* results. If true is supplied to this optional
* parameter then the outer brackets are removed
* from the returned group results.<br>
*
* @return (1D String Array) The determined nested groups desired.<br>
*
* @throws IllegalArgumentException if a depth is supplied greater than the
* available bracketed depth contained
* within the supplied input string. This
* exception is also thrown if it is found
* that the supplied Bracket Type is
* unbalanced (open and closed braces are
* not properly paired) within the supplied
* input string.
*/
public String[] getNestedBracketedGroups(String bracketedString, int desiredDepth,
String bracketType, boolean... removeOuterBrackets) {
boolean removeOuter = false;
if (removeOuterBrackets.length > 0) {
removeOuter = removeOuterBrackets[0];
}
int d = bracketsMaxDepth(bracketedString, bracketType);
if (desiredDepth == 0) {
//Default for this method is 0 (full depth).
desiredDepth = 1;
}
if (d == -1) {
// Throw Exception...
throw new IllegalArgumentException("\n\ngetNestedBracketedGroups() Method Error!\n"
+ "Brackets mismatch in supplied string!\n");
}
else if (d < desiredDepth) {
// Throw Another Exception...
throw new IllegalArgumentException("\n\ngetNestedBracketedGroups() Method Error!\n"
+ "Invalid Depth Supplied! Brackets within the supplied string go to a\n"
+ "maximum depth of (" + d + ") and therefore can not go to the supplied "
+ "depth\nof (" + desiredDepth + "). Change the desired depth.\n");
}
char open = '('; // Default
char close = ')'; // Default
String bType = Character.toString(open);
if (bracketType != null && !bracketType.trim().isEmpty()) {
bType = Character.toString(bracketType.trim().charAt(0));
}
switch (bType) {
case "(":
case ")":
open = '(';
close = ')';
break;
case "{":
case "}":
open = '{';
close = '}';
break;
case "[":
case "]":
open = '[';
close = ']';
break;
case "<":
case ">":
open = '<';
close = '>';
break;
default:
throw new IllegalArgumentException("\ngetNestedBracketedGroups() Method Error!\n"
+ "Unknown bracket type supplied (" + bType + ")!\n");
}
List<String> list = new ArrayList<>();
int n = bracketedString.length();
char[] c = bracketedString.toCharArray();
int depth = 0;
String strg = "";
for (int i = 0; i < n; i++) {
if (c[i] == open) {
depth++;
}
if ((depth >= desiredDepth)) {
if (c[i] == close) {
depth--;
}
strg += Character.toString(c[i]);
if (depth < desiredDepth) {
strg = strg.trim();
if (removeOuter) {
if (strg.startsWith(Character.toString(open))) {
strg = strg.substring(1);
}
if (strg.endsWith(Character.toString(close))) {
strg = strg.substring(0,
strg.lastIndexOf(Character.toString(close)));
}
}
list.add(strg);
strg = "";
}
continue;
}
if (c[i] == close) {
depth--;
}
if (!strg.isEmpty()) {
strg = strg.trim();
if (removeOuter) {
if (strg.startsWith(Character.toString(open))) {
strg = strg.substring(1);
}
if (strg.endsWith(Character.toString(close))) {
strg = strg.substring(0,
strg.lastIndexOf(Character.toString(close)));
}
}
list.add(strg);
strg = "";
}
}
if (!strg.isEmpty()) {
strg = strg.trim();
if (removeOuter) {
if (strg.startsWith(Character.toString(open))) {
strg = strg.substring(1);
}
if (strg.endsWith(Character.toString(close))) {
strg = strg.substring(0,
strg.lastIndexOf(Character.toString(close)));
}
}
list.add(strg);
}
return list.toArray(new String[list.size()]);
}
/**
* This method takes a string and returns the maximum depth of nested
* brackets. The bracket type to check the depth for is supplied within the
* bracketType parameter.<br><br>
*
* @param bracketedString (String) The string to process.<br>
*
* @param bracketType (String - Default is "()") Either a open bracket,
* or a close bracket, or both open and closed
* brackets can be supplied (no white-spaces). This
* method will process any <b>one</b> of 4 different
* bracket types and they are as follows:<pre>
*
* () Parentheses (Default)
* {} Curly Braces
* [] Square Brackets
* <> Chevron Brackets</pre>
*
* @return (Integer) The maximum depth of the supplied bracket type. 0 is
* returned if there are no brackets of the type supplied within the
* supplied string. -1 is returned if there is an unbalance within
* the supplied string of the supplied bracket type. For every open
* bracket there must be a close bracket and visa versa.
*/
public static int bracketsMaxDepth(String bracketedString, String... bracketType) {
char open = '('; // Default
char close = ')'; // Default
if (bracketType.length > 0) {
String bType = Character.toString(bracketType[0].charAt(0));
switch (bType) {
case "(":
case ")":
open = '(';
close = ')';
break;
case "{":
case "}":
open = '{';
close = '}';
break;
case "[":
case "]":
open = '[';
close = ']';
break;
case "<":
case ">":
open = '<';
close = '>';
break;
default:
throw new IllegalArgumentException("\nbracketsMaxDepth() Method Error!\n"
+ "Unknown bracket type supplied (" + bType + ")!\n");
}
}
int current_max = 0; // current count
int max = 0; // overall maximum count
int n = bracketedString.length();
char[] c = bracketedString.toCharArray();
// Traverse the input string
for (int i = 0; i < n; i++) {
if (c[i] == open) {
current_max++;
// update max if required
if (current_max > max) {
max = current_max;
}
}
else if (c[i] == close) {
if (current_max > 0) {
current_max--;
}
else {
return -1;
}
}
}
// finally check for unbalanced string
if (current_max != 0) {
return -1;
}
return max;
}
下面是一个如何使用这些方法的示例:
String string = "('fdmg') (R:Percentual ('dmg') (20))";
System.out.println("String with parentheses: " + string);
int maxBracketDepth = bracketsMaxDepth(string, "()");
System.out.println("Depth of nested parentheses: " + maxBracketDepth);
System.out.println();
System.out.println("WITH BRACKETS:");
System.out.println("==============");
for (int i = 1; i <= maxBracketDepth; i++) {
String[] a = getNestedBracketedGroups(string, i, "()");
System.out.println("Parenthesized groups at depth: " + i);
for (String b : a) {
System.out.println(b);
}
System.out.println();
}
System.out.println("WITHOUT BRACKETS:");
System.out.println("=================");
for (int i = 1; i <= maxBracketDepth; i++) {
String[] a = getNestedBracketedGroups(string, i, "()", true);
System.out.println("Parenthesized groups at depth: " + i);
for (String b : a) {
System.out.println(b);
}
System.out.println();
}
控制台窗口应显示:
String with parentheses: ('fdmg') (R:Percentual ('dmg') (20))
Depth of nested parentheses: 2
WITH BRACKETS:
==============
Parenthesized groups at depth: 1
('fdmg')
(R:Percentual ('dmg') (20))
Parenthesized groups at depth: 2
('dmg')
(20)
WITHOUT BRACKETS:
=================
Parenthesized groups at depth: 1
'fdmg'
R:Percentual ('dmg') (20)
Parenthesized groups at depth: 2
'dmg'
20
我的数据结构如下所示: Foo的每个实例都可以包含任意数量的S,这当然反过来又可以包含更多的S等等。那么,我该如何让FreeMarker通过这样的列表呢?
edit:作为标识字符串在模式中-请参见下面对gknicker答案的注释
我想我理解了教科书中对尾部递归函数的定义:在函数调用后不执行任何计算的函数。我还发现,作为一个结果,尾部递归函数的内存效率会更高,因为它每次调用只需要一条记录,而不是每次都需要保留一条记录(就像在普通递归中那样)。 我不太清楚的是,这个定义如何应用于嵌套调用。我将提供一个例子: 我最初给出的答案是,根据定义,它不是尾部递归的(因为外部调用是在计算内部调用之后执行的,所以其他计算是在第一次调用之后完
目前我有这个阵列= 条件: 如果每个嵌套数组index2都相同,那么我想用[0.0 1.0,1.0 2.0,2.0 3.0,3.0 4.0] = [1.0,3.0,5.0,7.0]来求和 我想要的最终结果:[[“efg”, [1.0, 3.0, 5.0, 7.0], “测试”]] 有什么方法或建议来获得这个结果吗?
问题内容: 我有一个方法必须执行以下操作: 我想指定嵌套的数量(在上述情况下,我希望嵌套15个)。这里有一种使用递归编程的方法吗? 问题答案: 是。这可以通过递归编程来执行。 我假设您不喜欢在源代码中写下这些嵌套的代码-如您的示例所示,因为这确实是丑陋的编程-如评论员所解释。 下面的代码(类似于Java的伪代码)对此进行了说明。我假设嵌套的深度固定。然后,您实际上想循环遍历尺寸深度的整数向量。 数
问题内容: 我正在尝试创建文件查看器,并且想嵌套子目录。我正在使用ui-router,我希望每个子目录都有其自己的URL和状态。 说我有以下结构: 我希望我的路线是: 我想递归地执行此操作,而不是为每个子目录创建一个新状态 问题答案: 我建议用 一种状态 和 一种参数 - 来做。因为应该尽快定义所有状态,以支持url路由。所有这些唯一的folderPath可能不同,也可能是动态的-在运行时中,在应