解析文件中的多个 json 类对象
Parsing multiple json like objects in a file
我正在尝试解析 F5 对象。它具有以下结构。
Some Garbage text
ltm virtual The_Name_51244_sdfasfdasd {
address-status yes
enabled
fallback-persistence none
profiles {
/Common/GLOBAL_PROFILE {
context all
}
/Common/http {
context all
}
}
rate-class none
rules {
/Common/X-F-F
}
log-profiles none
source-address-translation {
pool SOME-SNAT-POOL
type snat
}
source-port preserve
vlans {
Vlan1111
}
service-down-immediate-action none
service-policy none
source 0.0.0.0/0
}
barbage text
ltm virtual The_Object_51244 {
address-status yes
enabled
fallback-persistence none
profiles {
/Common/GLOBAL_PROFILE {
context all
}
/Common/http {
context all
}
}
rate-class none
rules {
/Common/X-F-F
}
log-profiles none
source-address-translation {
pool SOME-SNAT-POOL
type snat
}
source-port preserve
vlans {
Vlan2222
}
service-down-immediate-action none
service-policy none
source 0.0.0.0/0
}
Trailing garbage text
我的正则表达式是 ((ltm virtual) ([a-zA-Z0-9_-]*) {(.|\n)*?})
https://regex101.com/r/ATJZys/1
我要捕获的是 ltm virtual 之后的名称以及大括号之间的所有内容。但是,上面的正则表达式似乎首先停止了大括号匹配。
如何扩展它以匹配到下一个父组或匹配到大括号平衡?
您可以使用
((ltm virtual) ([a-zA-Z0-9_-]*) ({(?:[^{}]++|\g<4>)*}))
参见regex demo。
详情:
(
- 第 1 组开始
(ltm virtual)
- 第 2 组:ltm virtual
字符串
- space
([a-zA-Z0-9_-]*)
- 第 3 组:零个或多个字母、数字、下划线或连字符(可以是 re-written 作为 [\w-]*
)
- space
({(?:[^{}]++|\g<4>)*})
- 第 4 组:{
,然后 {
和 }
或第 4 组以外的一个或多个字符的零次或多次重复,并且然后是 }
字符
)
- 第 1 组结束。
在 Java 中,要匹配嵌套的花括号、圆括号或任何其他在特定正则表达式模式后的单个字符定界符(更准确地说是在模式末尾),您可以使用
import java.util.*;
import java.util.regex.*;
class Test
{
public static void main (String[] args) throws java.lang.Exception
{
Character markStart = '{';
Character markEnd = '}';
Boolean includeMarkers = true;
int offset = (includeMarkers ? -1 : 0);
String s = "Some Garbage text\r\nltm virtual The_Name_51244_sdfasfdasd {\r\n address-status yes\r\n enabled\r\n fallback-persistence none\r\n profiles {\r\n /Common/GLOBAL_PROFILE {\r\n context all\r\n }\r\n /Common/http {\r\n context all\r\n }\r\n }\r\n rate-class none\r\n rules {\r\n /Common/X-F-F\r\n }\r\n log-profiles none\r\n source-address-translation {\r\n pool SOME-SNAT-POOL\r\n type snat\r\n }\r\n source-port preserve\r\n vlans {\r\n Vlan1111\r\n }\r\n service-down-immediate-action none\r\n service-policy none\r\n source 0.0.0.0/0\r\n}\r\nbarbage text\r\nltm virtual The_Object_51244 {\r\n address-status yes\r\n enabled\r\n fallback-persistence none\r\n profiles {\r\n /Common/GLOBAL_PROFILE {\r\n context all\r\n }\r\n /Common/http {\r\n context all\r\n }\r\n }\r\n rate-class none\r\n rules {\r\n /Common/X-F-F\r\n }\r\n log-profiles none\r\n source-address-translation {\r\n pool SOME-SNAT-POOL\r\n type snat\r\n }\r\n source-port preserve\r\n vlans {\r\n Vlan2222\r\n }\r\n service-down-immediate-action none\r\n service-policy none\r\n source 0.0.0.0/0\r\n}\r\nTrailing garbage text";
Pattern patternBefore = Pattern.compile("(ltm\s+virtual)\s+([\w-]+)\s+" + Pattern.quote(markStart.toString()));
Matcher m = patternBefore.matcher(s);
while (m.find()) {
System.out.println("Group 1: " + m.group(1));
System.out.println("Group 2: " + m.group(2));
String res = getBalancedSubstring(s.substring(m.end()), markStart, markEnd, includeMarkers);
System.out.println("Found nested: " + res + "\n----");
if (res == null) {
System.out.println("No nested parens match found, this match must be failed.");
}
else {
s = s.substring(m.end()+res.length() + offset);
m.reset(s);
}
}
}
public static String getBalancedSubstring(String s, Character markStart, Character markEnd, Boolean includeMarkers)
{
int level = 1;
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (c == markStart) {
level++;
}
else if (c == markEnd) {
if (level == 1) {
return (includeMarkers ? markStart.toString() : "") + s.substring(0, (includeMarkers ? i + 1 : i));
}
if (level > 0) level--;
}
}
return null;
}
}
我正在尝试解析 F5 对象。它具有以下结构。
Some Garbage text
ltm virtual The_Name_51244_sdfasfdasd {
address-status yes
enabled
fallback-persistence none
profiles {
/Common/GLOBAL_PROFILE {
context all
}
/Common/http {
context all
}
}
rate-class none
rules {
/Common/X-F-F
}
log-profiles none
source-address-translation {
pool SOME-SNAT-POOL
type snat
}
source-port preserve
vlans {
Vlan1111
}
service-down-immediate-action none
service-policy none
source 0.0.0.0/0
}
barbage text
ltm virtual The_Object_51244 {
address-status yes
enabled
fallback-persistence none
profiles {
/Common/GLOBAL_PROFILE {
context all
}
/Common/http {
context all
}
}
rate-class none
rules {
/Common/X-F-F
}
log-profiles none
source-address-translation {
pool SOME-SNAT-POOL
type snat
}
source-port preserve
vlans {
Vlan2222
}
service-down-immediate-action none
service-policy none
source 0.0.0.0/0
}
Trailing garbage text
我的正则表达式是 ((ltm virtual) ([a-zA-Z0-9_-]*) {(.|\n)*?})
https://regex101.com/r/ATJZys/1
我要捕获的是 ltm virtual 之后的名称以及大括号之间的所有内容。但是,上面的正则表达式似乎首先停止了大括号匹配。
如何扩展它以匹配到下一个父组或匹配到大括号平衡?
您可以使用
((ltm virtual) ([a-zA-Z0-9_-]*) ({(?:[^{}]++|\g<4>)*}))
参见regex demo。
详情:
(
- 第 1 组开始(ltm virtual)
- 第 2 组:ltm virtual
字符串([a-zA-Z0-9_-]*)
- 第 3 组:零个或多个字母、数字、下划线或连字符(可以是 re-written 作为[\w-]*
)({(?:[^{}]++|\g<4>)*})
- 第 4 组:{
,然后{
和}
或第 4 组以外的一个或多个字符的零次或多次重复,并且然后是}
字符
)
- 第 1 组结束。
在 Java 中,要匹配嵌套的花括号、圆括号或任何其他在特定正则表达式模式后的单个字符定界符(更准确地说是在模式末尾),您可以使用
import java.util.*;
import java.util.regex.*;
class Test
{
public static void main (String[] args) throws java.lang.Exception
{
Character markStart = '{';
Character markEnd = '}';
Boolean includeMarkers = true;
int offset = (includeMarkers ? -1 : 0);
String s = "Some Garbage text\r\nltm virtual The_Name_51244_sdfasfdasd {\r\n address-status yes\r\n enabled\r\n fallback-persistence none\r\n profiles {\r\n /Common/GLOBAL_PROFILE {\r\n context all\r\n }\r\n /Common/http {\r\n context all\r\n }\r\n }\r\n rate-class none\r\n rules {\r\n /Common/X-F-F\r\n }\r\n log-profiles none\r\n source-address-translation {\r\n pool SOME-SNAT-POOL\r\n type snat\r\n }\r\n source-port preserve\r\n vlans {\r\n Vlan1111\r\n }\r\n service-down-immediate-action none\r\n service-policy none\r\n source 0.0.0.0/0\r\n}\r\nbarbage text\r\nltm virtual The_Object_51244 {\r\n address-status yes\r\n enabled\r\n fallback-persistence none\r\n profiles {\r\n /Common/GLOBAL_PROFILE {\r\n context all\r\n }\r\n /Common/http {\r\n context all\r\n }\r\n }\r\n rate-class none\r\n rules {\r\n /Common/X-F-F\r\n }\r\n log-profiles none\r\n source-address-translation {\r\n pool SOME-SNAT-POOL\r\n type snat\r\n }\r\n source-port preserve\r\n vlans {\r\n Vlan2222\r\n }\r\n service-down-immediate-action none\r\n service-policy none\r\n source 0.0.0.0/0\r\n}\r\nTrailing garbage text";
Pattern patternBefore = Pattern.compile("(ltm\s+virtual)\s+([\w-]+)\s+" + Pattern.quote(markStart.toString()));
Matcher m = patternBefore.matcher(s);
while (m.find()) {
System.out.println("Group 1: " + m.group(1));
System.out.println("Group 2: " + m.group(2));
String res = getBalancedSubstring(s.substring(m.end()), markStart, markEnd, includeMarkers);
System.out.println("Found nested: " + res + "\n----");
if (res == null) {
System.out.println("No nested parens match found, this match must be failed.");
}
else {
s = s.substring(m.end()+res.length() + offset);
m.reset(s);
}
}
}
public static String getBalancedSubstring(String s, Character markStart, Character markEnd, Boolean includeMarkers)
{
int level = 1;
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (c == markStart) {
level++;
}
else if (c == markEnd) {
if (level == 1) {
return (includeMarkers ? markStart.toString() : "") + s.substring(0, (includeMarkers ? i + 1 : i));
}
if (level > 0) level--;
}
}
return null;
}
}