Answers:
您应该能够使用非贪婪的量词,特别是*?。您可能需要以下条件:
Pattern MY_PATTERN = Pattern.compile("\\[(.*?)\\]");
这将为您提供一个与您的字符串匹配的模式,并将文本放在第一组的方括号内。请查看Pattern API文档以获取更多信息。
要提取字符串,可以使用如下所示的内容:
Matcher m = MY_PATTERN.matcher("FOO[BAR]");
while (m.find()) {
String s = m.group(1);
// s now contains "BAR"
}
非正则表达式方式:
String input = "FOO[BAR]", extracted;
extracted = input.substring(input.indexOf("["),input.indexOf("]"));
或者,为了获得更好的性能/内存使用(感谢Hosam):
String input = "FOO[BAR]", extracted;
extracted = input.substring(input.indexOf('['),input.lastIndexOf(']'));
lastIndexOf(']')
处理嵌套括号的方法。另外,我相信使用indexOf(char)
会比快indexOf(String)
。
lastIndexOf
找到结束括号肯定会更快。
这是一个工作示例:
RegexpExample.java
package org.regexp.replace;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexpExample
{
public static void main(String[] args)
{
String string = "var1[value1], var2[value2], var3[value3]";
Pattern pattern = Pattern.compile("(\\[)(.*?)(\\])");
Matcher matcher = pattern.matcher(string);
List<String> listMatches = new ArrayList<String>();
while(matcher.find())
{
listMatches.add(matcher.group(2));
}
for(String s : listMatches)
{
System.out.println(s);
}
}
}
它显示:
value1
value2
value3
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public static String get_match(String s, String p) {
// returns first match of p in s for first group in regular expression
Matcher m = Pattern.compile(p).matcher(s);
return m.find() ? m.group(1) : "";
}
get_match("FOO[BAR]", "\\[(.*?)\\]") // returns "BAR"
public static List<String> get_matches(String s, String p) {
// returns all matches of p in s for first group in regular expression
List<String> matches = new ArrayList<String>();
Matcher m = Pattern.compile(p).matcher(s);
while(m.find()) {
matches.add(m.group(1));
}
return matches;
}
get_matches("FOO[BAR] FOO[CAT]", "\\[(.*?)\\]")) // returns [BAR, CAT]
如果您只需要获取之间的任何值[]
,则可以这样使用\[([^\]]*)\]
:
Pattern regex = Pattern.compile("\\[([^\\]]*)\\]");
Matcher m = regex.matcher(str);
if (m.find()) {
result = m.group();
}
如果您需要它的形式,identifier + [ + content + ]
那么仅当标识符为字母数字时,才可以限制提取内容:
[a-zA-Z][a-z-A-Z0-9_]*\s*\[([^\]]*)\]
这将验证之类的东西Foo [Bar]
,或myDevice_123["input"]
为实例。
主要问题
主要问题是当您要提取类似以下内容的内容时:
FOO[BAR[CAT[123]]+DOG[FOO]]
正则表达式将无法正常运行,并且会返回BAR[CAT[123
和FOO
。
如果我们将正则表达式更改为,\[(.*)\]
则可以,但是,如果您尝试从更复杂的内容中提取内容,例如:
FOO[BAR[CAT[123]]+DOG[FOO]] = myOtherFoo[BAR[5]]
这些正则表达式均无法使用。
在所有情况下提取正确内容的最准确的Regex会复杂得多,因为它需要平衡[]
对并为它们提供内容。
一个更简单的解决方案
如果您的问题变得越来越复杂并且内容的[]
任意性[]
更大,则可以使用普通的旧代码rathe而不是Regex 来平衡两对并提取字符串:
int i;
int brackets = 0;
string c;
result = "";
for (i = input.indexOf("["); i < str.length; i++) {
c = str.substring(i, i + 1);
if (c == '[') {
brackets++;
} else if (c == ']') {
brackets--;
if (brackets <= 0)
break;
}
result = result + c;
}
这是比真实代码更多的伪代码,我不是Java程序员,所以我不知道语法是否正确,但是应该很容易进行改进。
重要的是,此代码应该有效,并允许您提取的内容[]
,无论它多么复杂。
我认为您的正则表达式如下所示:
/FOO\[(.+)\]/
假设FOO将保持不变。
因此,将其放入Java中:
Pattern p = Pattern.compile("FOO\\[(.+)\\]");
Matcher m = p.matcher(inputLine);
我定义了在[
和之间需要最大数量的非[]字符]
。这些需要用反斜杠转义(在Java中,它们需要再次转义),并且non-]的定义是一个字符类,因此位于[
and ]
(即[^\\]]
)内。结果:
FOO\\[([^\\]]+)\\]
像这样,如果您要解析来自mYearInDB.toString()= [2013]的字符串,它将得到2013
Matcher n = MY_PATTERN.matcher("FOO[BAR]"+mYearInDB.toString());
while (n.find()) {
extracredYear = n.group(1);
// s now contains "BAR"
}
System.out.println("Extrated output is : "+extracredYear);
此正则表达式适用于我:
form\[([^']*?)\]
例:
form[company_details][0][name]
form[company_details][0][common_names][1][title]
输出:
Match 1
1. company_details
Match 2
1. company_details
"FOO[DOG]".replaceAll("^.*?\\[|\\].*", "");
这将返回仅在方括号内包含字符串的字符串。
这将从方括号中移出所有外部字符串。
您可以在线测试此Java示例代码:http : //tpcg.io/wZoFu0
您可以从以下位置测试此正则表达式:https : //regex101.com/r/oUAzsS/1