l43_rgx 0.1.0
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 +7 -0
- data/lib/l43/rgx/all.rb +7 -0
- data/lib/l43/rgx/compile.rb +86 -0
- data/lib/l43/rgx/errors.rb +8 -0
- data/lib/l43/rgx/methods.rb +41 -0
- data/lib/l43/rgx/result.rb +23 -0
- data/lib/l43/rgx/version.rb +8 -0
- data/lib/l43/rgx.rb +84 -0
- metadata +76 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 16234666a82b0ee1a42c90674890ec10a4ae5e64ae38c067520e51c4bec64796
|
|
4
|
+
data.tar.gz: 2472f2c910a99c485b67c31c43012be28c6516b428c3d3a7dd87ec8754935586
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 3d4d321341fa59397399d892a8e224999932534739b91aaa26925e0ee2d3e43aab8734fcb986fa4ceda8ba892d968b70fe80436532424787bb6bd911077b09b8
|
|
7
|
+
data.tar.gz: 916dc34de7fc7589c809ad916eed701798de220efbaf6478993bba32f78a11bcb941f13fefa75c23ef8ef0c17170b7454c17b2126b66a4e59ee5baeec43d5e5f
|
data/lib/l43/rgx/all.rb
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module L43
|
|
4
|
+
class Rgx
|
|
5
|
+
module Compile
|
|
6
|
+
|
|
7
|
+
private
|
|
8
|
+
def _a_anchor
|
|
9
|
+
"\\A" if [:begin, :both].member?(anchored)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def _capture_rest
|
|
13
|
+
@___capture_rest__ ||= "(.*)\\z" if capture_rest
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def _compile
|
|
17
|
+
@source = [a_anchor, look_behind, compiled_parts, look_ahead, _capture_rest, z_anchor].join.freeze
|
|
18
|
+
@regexp = Regexp.compile(source).freeze
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def _compile_part(part, level: 0)
|
|
22
|
+
case part
|
|
23
|
+
in String
|
|
24
|
+
part
|
|
25
|
+
in Symbol
|
|
26
|
+
repr = part.to_s
|
|
27
|
+
if repr.end_with?("s")
|
|
28
|
+
"[[:#{repr[0...-1]}:]]+"
|
|
29
|
+
else
|
|
30
|
+
"[[:#{repr}:]]"
|
|
31
|
+
end
|
|
32
|
+
in Integer
|
|
33
|
+
"{#{part}}"
|
|
34
|
+
in Range
|
|
35
|
+
"{#{part.first},#{part.last}}"
|
|
36
|
+
in Array
|
|
37
|
+
raise CompilationError, "nested groups are not allowed" if level.positive?
|
|
38
|
+
"(#{part.map { _compile_part(it, level: level.succ) }.join})"
|
|
39
|
+
else
|
|
40
|
+
if self.class === part
|
|
41
|
+
raise CompilationError, "part is anchored, only use unanchored instances of #{self.class}" if part.anchored?
|
|
42
|
+
part.source
|
|
43
|
+
else
|
|
44
|
+
raise CompilationError, "part: #{part.inspect} needs to be a string, symbol, integer or range"
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def _compiled_parts
|
|
50
|
+
parts.map { _compile_part it }.join
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def _look_ahead
|
|
54
|
+
if followed_by
|
|
55
|
+
followed = self.class.new(*Array(followed_by)).source
|
|
56
|
+
"(?=#{followed})"
|
|
57
|
+
elsif not_followed_by
|
|
58
|
+
followed = self.class.new(*Array(not_followed_by)).source
|
|
59
|
+
"(?!#{followed})"
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def _look_behind
|
|
64
|
+
if preceded_by
|
|
65
|
+
preceded = self.class.new(*Array(preceded_by)).source
|
|
66
|
+
"(?<=#{preceded})"
|
|
67
|
+
elsif not_preceded_by
|
|
68
|
+
preceded = self.class.new(*Array(not_preceded_by)).source
|
|
69
|
+
"(?<!#{preceded})"
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def _z_anchor
|
|
74
|
+
"\\z" if [:end, :both].member?(anchored)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def a_anchor = @__a_anchor__ ||= _a_anchor
|
|
78
|
+
def compiled_parts = @__compiled_parts__ ||= _compiled_parts
|
|
79
|
+
def look_ahead = @___look_ahead__ ||= _look_ahead
|
|
80
|
+
def look_behind = @___look_behind__ ||= _look_behind
|
|
81
|
+
def z_anchor = @__z_anchor__ ||= _z_anchor
|
|
82
|
+
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module L43
|
|
4
|
+
class Rgx
|
|
5
|
+
module Methods
|
|
6
|
+
|
|
7
|
+
def or(*parts, **options)
|
|
8
|
+
self.class.new(wrap, "|", self.class.new(*parts, **options).wrap)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def many(min: 0)
|
|
12
|
+
inner_part = wrap
|
|
13
|
+
new_source =
|
|
14
|
+
case min
|
|
15
|
+
in 0
|
|
16
|
+
"#{inner_part}*"
|
|
17
|
+
in 1
|
|
18
|
+
"#{inner_part}+"
|
|
19
|
+
else
|
|
20
|
+
"#{inner_part}{#{min},}"
|
|
21
|
+
end
|
|
22
|
+
self.class.new(new_source)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def wrap = _wrap(self)
|
|
26
|
+
|
|
27
|
+
private
|
|
28
|
+
def _wrap(part)
|
|
29
|
+
case part
|
|
30
|
+
when String
|
|
31
|
+
"(?:#{part})"
|
|
32
|
+
when Rgx
|
|
33
|
+
"(?:#{part.source})"
|
|
34
|
+
else
|
|
35
|
+
raise ArgumentError, "_wrap needs string or rgx, not #{part.inspect}"
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module L43
|
|
4
|
+
class Rgx
|
|
5
|
+
class Result
|
|
6
|
+
|
|
7
|
+
attr_reader :captures
|
|
8
|
+
|
|
9
|
+
def deconstruct(*) = captures
|
|
10
|
+
|
|
11
|
+
def ==(other)
|
|
12
|
+
self.class === other && captures == other.captures
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
private
|
|
16
|
+
def initialize(captures)
|
|
17
|
+
@captures = captures.freeze
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
# SPDX-License-Identifier: AGPL-3.0-or-later
|
data/lib/l43/rgx.rb
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'rgx/errors'
|
|
4
|
+
require_relative 'rgx/compile'
|
|
5
|
+
require_relative 'rgx/methods'
|
|
6
|
+
require_relative 'rgx/result'
|
|
7
|
+
require 'l43/core/forwarder'
|
|
8
|
+
|
|
9
|
+
module L43
|
|
10
|
+
class Rgx
|
|
11
|
+
extend L43::Core::Forwarder
|
|
12
|
+
include Compile
|
|
13
|
+
include Methods
|
|
14
|
+
|
|
15
|
+
LegalAnchors = [nil, :begin, :both, :end].freeze
|
|
16
|
+
|
|
17
|
+
attr_reader :regexp, :source
|
|
18
|
+
forward :match, to: :regexp
|
|
19
|
+
|
|
20
|
+
def anchored? = anchored || capture_rest
|
|
21
|
+
def anchored_at_begin? = [:begin, :both].member?(anchored)
|
|
22
|
+
def anchored_at_end? = [:end, :both].member?(anchored)
|
|
23
|
+
|
|
24
|
+
def run(subject, include_match: false)
|
|
25
|
+
case regexp.match(subject)
|
|
26
|
+
in nil
|
|
27
|
+
nil
|
|
28
|
+
in md
|
|
29
|
+
if callback
|
|
30
|
+
Result.new(Array(callback.(*md.to_a)))
|
|
31
|
+
else
|
|
32
|
+
include_match ? Result.new(md.to_a) : Result.new(md.captures)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
private
|
|
38
|
+
attr_reader \
|
|
39
|
+
:anchored,
|
|
40
|
+
:callback, :capture_rest,
|
|
41
|
+
:followed_by,
|
|
42
|
+
:not_followed_by, :not_preceded_by,
|
|
43
|
+
:parts, :preceded_by
|
|
44
|
+
|
|
45
|
+
def initialize(*parts,
|
|
46
|
+
anchored: nil,
|
|
47
|
+
capture_rest: false,
|
|
48
|
+
followed_by: nil,
|
|
49
|
+
not_followed_by: nil,
|
|
50
|
+
not_preceded_by: nil,
|
|
51
|
+
preceded_by: nil,
|
|
52
|
+
&callback)
|
|
53
|
+
|
|
54
|
+
raise ArgumentError, "must not provide followed_by and not_followed_by at the same time" if followed_by && not_followed_by
|
|
55
|
+
raise ArgumentError, "must not provide preceded_by and not_preceded_by at the same time" if preceded_by && not_preceded_by
|
|
56
|
+
raise ArgumentError, "illegal value for keyword argument capture_rest, must be a boolean, but was #{capture_rest.inspect}" unless
|
|
57
|
+
[false, true].member?(capture_rest)
|
|
58
|
+
raise ArgumentError, "illegal value for keyword argument anchored, must be in #{LegalAnchors.inspect}, but was: #{anchored.inspect}" unless
|
|
59
|
+
LegalAnchors.member?(anchored)
|
|
60
|
+
|
|
61
|
+
@anchored = anchored
|
|
62
|
+
raise ArgumentError, "must not use capture_rest with anchored :end or :both" if anchored_at_end? && capture_rest
|
|
63
|
+
raise ArgumentError, "must not use lookahead assertion (followed_by) with anchored :end or :both" if anchored_at_end? && followed_by
|
|
64
|
+
raise ArgumentError, "must not use negative lookahead assertion (not_followed_by) with anchored :end or :both" if anchored_at_end? && not_followed_by
|
|
65
|
+
raise ArgumentError, "must not use negative lookahead assertion (not_followed_by) with capture_rest" if anchored_at_end? && capture_rest
|
|
66
|
+
|
|
67
|
+
raise ArgumentError, "must not use lookbehind assertion (preceded_by) with anchored :begin or :both" if anchored_at_begin? && preceded_by
|
|
68
|
+
raise ArgumentError, "must not use negative lookbehind assertion (not_preceded_by) with anchored :begin or :both" if anchored_at_begin? && not_preceded_by
|
|
69
|
+
|
|
70
|
+
@anchored = anchored
|
|
71
|
+
@callback = callback
|
|
72
|
+
@capture_rest = capture_rest
|
|
73
|
+
@followed_by = followed_by
|
|
74
|
+
@not_followed_by = not_followed_by
|
|
75
|
+
@not_preceded_by = not_preceded_by
|
|
76
|
+
@parts = parts.freeze
|
|
77
|
+
@preceded_by = preceded_by
|
|
78
|
+
|
|
79
|
+
_compile
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
# SPDX-License-Identifier: AGPL-3.0-or-later
|
metadata
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: l43_rgx
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Robert Dober
|
|
8
|
+
bindir: bin
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 2026-09-08 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: ostruct
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - "~>"
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: 0.6.3
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - "~>"
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: 0.6.3
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: l43_core
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - "~>"
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: 0.2.9
|
|
33
|
+
type: :runtime
|
|
34
|
+
prerelease: false
|
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - "~>"
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: 0.2.9
|
|
40
|
+
description: 'Human Readable Regexp Wrapper and Tools
|
|
41
|
+
|
|
42
|
+
'
|
|
43
|
+
email: robert.dober@gmail.com
|
|
44
|
+
executables: []
|
|
45
|
+
extensions: []
|
|
46
|
+
extra_rdoc_files: []
|
|
47
|
+
files:
|
|
48
|
+
- lib/l43/rgx.rb
|
|
49
|
+
- lib/l43/rgx/all.rb
|
|
50
|
+
- lib/l43/rgx/compile.rb
|
|
51
|
+
- lib/l43/rgx/errors.rb
|
|
52
|
+
- lib/l43/rgx/methods.rb
|
|
53
|
+
- lib/l43/rgx/result.rb
|
|
54
|
+
- lib/l43/rgx/version.rb
|
|
55
|
+
homepage: https://codeberg.org/lab419/l43_rgx
|
|
56
|
+
licenses:
|
|
57
|
+
- AGPL-3.0-or-later
|
|
58
|
+
metadata: {}
|
|
59
|
+
rdoc_options: []
|
|
60
|
+
require_paths:
|
|
61
|
+
- lib
|
|
62
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
63
|
+
requirements:
|
|
64
|
+
- - ">="
|
|
65
|
+
- !ruby/object:Gem::Version
|
|
66
|
+
version: 4.0.2
|
|
67
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
68
|
+
requirements:
|
|
69
|
+
- - ">="
|
|
70
|
+
- !ruby/object:Gem::Version
|
|
71
|
+
version: '0'
|
|
72
|
+
requirements: []
|
|
73
|
+
rubygems_version: 4.0.19
|
|
74
|
+
specification_version: 4
|
|
75
|
+
summary: Human Readable Regexp Wrapper and Tools
|
|
76
|
+
test_files: []
|