textfsm 0.4.0 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/README.md +6 -2
- data/lib/textfsm/index_table.rb +12 -6
- data/lib/textfsm/parser.rb +2 -3
- data/lib/textfsm/pattern.rb +2 -1
- data/lib/textfsm/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e4032e879606f9930b18496dc11d5ee391891ebc206d3a18ff7ad8bac909c881
|
|
4
|
+
data.tar.gz: dc4767adf5127b8a799ec83498d18bf6f065ad85f8ee3e88f465eb4057fbb548
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0170443b06fb0b0e0d564b23b5fa386a868fddffccb03360d38be2b88425224a308e379d2416a39b886e50f3ae8a4010808d8c816fe15d9c0b990a92e3266c15
|
|
7
|
+
data.tar.gz: 19c0e4375e5f4a12e820feb36cfe220ae0f9ca75b255b800e47fe11817e066cc555b0b39afc2f9bc2135b1250bbe30b4a15996b72d8bbefa5fb7fce7d7c2239c
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
|
@@ -31,7 +31,7 @@ gem "textfsm", path: "/path/to/textfsm"
|
|
|
31
31
|
```sh
|
|
32
32
|
bundle install
|
|
33
33
|
bundle exec rake build
|
|
34
|
-
gem install ./pkg/textfsm-0.4.
|
|
34
|
+
gem install ./pkg/textfsm-0.4.1.gem
|
|
35
35
|
```
|
|
36
36
|
|
|
37
37
|
源码仓库:[gatework/textfsm](https://github.com/gatework/textfsm)。
|
|
@@ -185,6 +185,8 @@ cisco_version_template, Cisco, sh[[ow]] ve[[rsion]]
|
|
|
185
185
|
|
|
186
186
|
每次查询按需将参与匹配的属性值转换为字符串,并在本次扫描中复用;未知属性和仅遇到通配条件的值不会触发转换。Symbol 与同名 String 属性分别参与匹配,传入的属性集合不会被修改。
|
|
187
187
|
|
|
188
|
+
加载索引时,相同模式在当前索引内只编译一次;`IndexTable` 的 `transform:` 和 `compile:` 回调仍按文件顺序逐单元格执行,回调返回值不会被原地修改。
|
|
189
|
+
|
|
188
190
|
可绕过 index 显式传入模板:
|
|
189
191
|
|
|
190
192
|
```ruby
|
|
@@ -260,7 +262,7 @@ parser = TextFSM::Parser.new(template, options: { "Uppercase" => Uppercase })
|
|
|
260
262
|
工作流验证并上传同次 CI 的 gem,再核对 RubyGems 下载和 GitHub Release 的 SHA256。
|
|
261
263
|
流程、账号绑定及失败恢复见 [发布说明](docs/RELEASING.md)。
|
|
262
264
|
|
|
263
|
-
本地预检可执行 `bundle exec ruby script/release.rb --dry-run --artifact pkg/textfsm-0.4.
|
|
265
|
+
本地预检可执行 `bundle exec ruby script/release.rb --dry-run --artifact pkg/textfsm-0.4.1.gem`;
|
|
264
266
|
已有产物路径不会重新构建。更新版本及 CHANGELOG、提交并确认远端 CI 后推送对应版本标签。
|
|
265
267
|
|
|
266
268
|
## 兼容范围与验证
|
|
@@ -269,6 +271,8 @@ parser = TextFSM::Parser.new(template, options: { "Uppercase" => Uppercase })
|
|
|
269
271
|
|
|
270
272
|
Ruby 使用 Onigmo 正则引擎。本项目转换 Python 命名组 `(?P<name>...)`、命名与数字反向引用、贪婪/懒惰/占有量词、常用内联标志 `i/m/s/x/a/u`、Unicode 字符类及锚点语义。**这不是完整 Python `re` 引擎的替代实现**:Unicode 名称转义 `\N{...}`、条件组等不支持的扩展会报 `TemplateError`;两种引擎的大小写折叠、复杂后行断言等细节仍可能不同。使用额外模板库时,应以实际模板与输入执行对照测试。
|
|
271
273
|
|
|
274
|
+
多行模式的 `^` 匹配输入开头或换行后的位置,包括末尾换行后的空行。可匹配空串的重复组仍可能有不同的回溯结果,例如 `(?:\ba?){2}` 在 `"aa"` 上的匹配长度与 Python 不同;依赖这类行为的模板需单独对照验证。
|
|
275
|
+
|
|
272
276
|
直接使用 `Pattern` 时,`named_captures(match)` 返回命名捕获的 Hash;`each_capture(match)` 按定义顺序逐项产出名称和值,保留未匹配组的 `nil`,无块时返回 Enumerator。Parser 使用逐项迭代传递字段值,避免为每条匹配规则构造临时 Hash。
|
|
273
277
|
|
|
274
278
|
模板字符串须使用有效且兼容 ASCII 的编码,模板文件和索引文件按 UTF-8 读取。模板或正则的无效编码报告 `TemplateError`,索引的无效编码报告带路径与行号的 `IndexError`;`CliTable` 保留此前成功解析的数据和索引。
|
data/lib/textfsm/index_table.rb
CHANGED
|
@@ -22,12 +22,7 @@ module TextFSM
|
|
|
22
22
|
|
|
23
23
|
def initialize(path, transform: nil, compile: nil)
|
|
24
24
|
@header, @rows = Data.copy(read_table(path, transform), immutable: true)
|
|
25
|
-
@patterns =
|
|
26
|
-
row.to_h do |key, value|
|
|
27
|
-
value = compile.call(key, value) if compile
|
|
28
|
-
[key, value.nil? || value.empty? ? nil : Pattern.new(value)]
|
|
29
|
-
end.freeze
|
|
30
|
-
end.freeze
|
|
25
|
+
@patterns = compile_patterns(compile)
|
|
31
26
|
freeze
|
|
32
27
|
rescue TemplateError => e
|
|
33
28
|
raise IndexError, "#{path}: #{e.message}"
|
|
@@ -69,6 +64,17 @@ module TextFSM
|
|
|
69
64
|
|
|
70
65
|
private
|
|
71
66
|
|
|
67
|
+
def compile_patterns(compile)
|
|
68
|
+
# 仅在本次构建中共享不可变模式;回调仍逐单元格执行,缓存不跨索引保留。
|
|
69
|
+
compiled = {}
|
|
70
|
+
@rows.map do |row|
|
|
71
|
+
row.to_h do |key, value|
|
|
72
|
+
value = compile.call(key, value) if compile
|
|
73
|
+
[key, value.nil? || value.empty? ? nil : (compiled[value] ||= Pattern.new(value))]
|
|
74
|
+
end.freeze
|
|
75
|
+
end.freeze
|
|
76
|
+
end
|
|
77
|
+
|
|
72
78
|
def read_table(path, transform)
|
|
73
79
|
lines = File.foreach(path, encoding: "UTF-8")
|
|
74
80
|
header = nil
|
data/lib/textfsm/parser.rb
CHANGED
|
@@ -124,11 +124,10 @@ module TextFSM
|
|
|
124
124
|
text = text.read if text.respond_to?(:read)
|
|
125
125
|
raise ArgumentError, "text must be a String or readable IO" unless text.is_a?(String)
|
|
126
126
|
|
|
127
|
-
#
|
|
128
|
-
# allocating all lines or repeatedly finding character offsets.
|
|
127
|
+
# scan_until 返回新字符串;chop! 原地移除一个分隔字符或整对 CRLF。
|
|
129
128
|
scanner = StringScanner.new(text)
|
|
130
129
|
while (line = scanner.scan_until(LINE_SEPARATOR))
|
|
131
|
-
process_line(line.
|
|
130
|
+
process_line(line.chop!)
|
|
132
131
|
break if terminal?
|
|
133
132
|
end
|
|
134
133
|
process_line(scanner.rest) unless terminal? || scanner.eos?
|
data/lib/textfsm/pattern.rb
CHANGED
|
@@ -109,7 +109,8 @@ module TextFSM
|
|
|
109
109
|
end
|
|
110
110
|
|
|
111
111
|
def anchor(character)
|
|
112
|
-
|
|
112
|
+
# Ruby 的 ^ 不匹配末尾换行后的空行,需显式保留 Python 的起始位置。
|
|
113
|
+
return character == "^" ? "(?:\\A|(?<=\\n))" : "$" if @flags[:multiline]
|
|
113
114
|
|
|
114
115
|
character == "^" ? "\\A" : "\\Z"
|
|
115
116
|
end
|
data/lib/textfsm/version.rb
CHANGED