解析 Cisco 路由器配置块
Parsing Cisco router configuration blocks
我正在尝试解析思科配置。它具有如下所示的缩进结构。有很多这样的块。有些块可以更长。 !
符号表示上述缩进结束。如何解析块下的块和子块?
Ex1 :
XXXXXXXXXXX
XXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXX \
XXXXXXXXXXXX \ |
XXXXXX | sub-block | block
XXXXXX | |
! / |
! /
XXXXXXXXXXXXX
XXXXXXXXXXXXX
XXXXXXXXXXXX
XXXXXX
Ex2 :
XXXXXXXXXXX
XXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXX \
XXXXXXXXXXXX \ |
XXXXXX | sub-block | block
XXXXXX | |
! / |
XXXXXXXXXXXX \ |
XXXXXX | sub-block |
! / |
! /
XXXXXXXXXXXXX
XXXXXXXXXXXXX
XXXXXXXXXXXX
XXXXXX
Ex3 - 真正的思科配置:
vrf myvrfvir
address-family ipv4 broadcast
import route
10:10
!
export route
20:20
!
!
!
interface Eth6/3/9/4.10
description vlan10
mtu 1500
dot1q vlan 10
!
.
.
.
有4块:
- 第一个块名称是
vrf myvrfvir
,
- 第二个块名称是
interface GigabitEth0/3/5/3.10
,
- 第 3 个(子)块是
import route
、
- 第 4 个(子)块是
export route
。
所以我希望能够获取所有块并将它们存储在散列、列表、文本或...
所以我想在需要时到达每个块及其块和上层块名称。
最简单的方法是将块数据存储在地图中:
class Block {
private Map<String, String> data;
private Block parent;
private List<Block> children;
}
另外,您可以创建另一个数据结构来满足您的需要/解决您手头的任务。
然后,逐行读取文件,通过跟踪缩进数来检测是否需要新块,并填充上面的数据结构。
快速而肮脏的示例(免责声明:我没有 运行 这段代码,那只是为了让你开始,你应该添加验证,将它拆分成多个函数等,以便它干净,正确,很高兴阅读):
try (BufferedReader bufferedReader = new BufferedReader(reader)) {
Block block = new Block();
String line, previousIndents = "";
while (null != (line = bufferedReader.readLine()) {
Matcher m = Pattern.compile("^(\s+)").matcher(line);
if (m.find()) {
String indents = m.group(1);
if (previousIndents.equals(indents)) {
// update current block
} else if (indents.length() > previousIndents.length()) {
// start a new block
Block newBlock = new Block();
newBlock.setParent(block);
block.getChildren().add(newBlock);
block = newBlock;
} else {
// current block finished, return to parent
block = block.getParent();
}
previousIndents = indents;
}
}
}
catch (IOException ioEx) {
throw new ParseException(ioEx);
}
我正在尝试解析思科配置。它具有如下所示的缩进结构。有很多这样的块。有些块可以更长。 !
符号表示上述缩进结束。如何解析块下的块和子块?
Ex1 :
XXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX \ XXXXXXXXXXXX \ | XXXXXX | sub-block | block XXXXXX | | ! / | ! / XXXXXXXXXXXXX XXXXXXXXXXXXX XXXXXXXXXXXX XXXXXX
Ex2 :
XXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX \ XXXXXXXXXXXX \ | XXXXXX | sub-block | block XXXXXX | | ! / | XXXXXXXXXXXX \ | XXXXXX | sub-block | ! / | ! / XXXXXXXXXXXXX XXXXXXXXXXXXX XXXXXXXXXXXX XXXXXX
Ex3 - 真正的思科配置:
vrf myvrfvir address-family ipv4 broadcast import route 10:10 ! export route 20:20 ! ! ! interface Eth6/3/9/4.10 description vlan10 mtu 1500 dot1q vlan 10 ! . . .
有4块:
- 第一个块名称是
vrf myvrfvir
, - 第二个块名称是
interface GigabitEth0/3/5/3.10
, - 第 3 个(子)块是
import route
、 - 第 4 个(子)块是
export route
。
所以我希望能够获取所有块并将它们存储在散列、列表、文本或...
所以我想在需要时到达每个块及其块和上层块名称。
- 第一个块名称是
最简单的方法是将块数据存储在地图中:
class Block {
private Map<String, String> data;
private Block parent;
private List<Block> children;
}
另外,您可以创建另一个数据结构来满足您的需要/解决您手头的任务。
然后,逐行读取文件,通过跟踪缩进数来检测是否需要新块,并填充上面的数据结构。
快速而肮脏的示例(免责声明:我没有 运行 这段代码,那只是为了让你开始,你应该添加验证,将它拆分成多个函数等,以便它干净,正确,很高兴阅读):
try (BufferedReader bufferedReader = new BufferedReader(reader)) {
Block block = new Block();
String line, previousIndents = "";
while (null != (line = bufferedReader.readLine()) {
Matcher m = Pattern.compile("^(\s+)").matcher(line);
if (m.find()) {
String indents = m.group(1);
if (previousIndents.equals(indents)) {
// update current block
} else if (indents.length() > previousIndents.length()) {
// start a new block
Block newBlock = new Block();
newBlock.setParent(block);
block.getChildren().add(newBlock);
block = newBlock;
} else {
// current block finished, return to parent
block = block.getParent();
}
previousIndents = indents;
}
}
}
catch (IOException ioEx) {
throw new ParseException(ioEx);
}