annotate src/luan/modules/RegexLuan.java @ 1802:ca98dee04e08 default tip

add Parsers.json_null
author Franklin Schmidt <fschmidt@gmail.com>
date Sun, 21 Apr 2024 21:25:15 -0600
parents e59349d53fec
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1716
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
1 package luan.modules;
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
2
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
3 import java.util.regex.Pattern;
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
4 import java.util.regex.Matcher;
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
5 import luan.Luan;
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
6 import luan.LuanMutable;
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
7 import luan.LuanTable;
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
8 import luan.LuanFunction;
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
9 import luan.LuanException;
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
10
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
11
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
12 public final class RegexLuan implements LuanMutable {
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
13 public Pattern pattern;
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
14 private boolean immutable = false;
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
15
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
16 public RegexLuan(String s) {
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
17 this.pattern = Pattern.compile(s);
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
18 }
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
19
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
20 @Override public boolean isImmutable() {
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
21 return immutable;
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
22 }
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
23
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
24 @Override public void makeImmutable() {
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
25 if(immutable)
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
26 return;
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
27 immutable = true;
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
28 }
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
29
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
30 public void set(String s) throws LuanException {
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
31 if( immutable )
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
32 throw new LuanException("regex is immutable");
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
33 this.pattern = Pattern.compile(s);
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
34 }
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
35
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
36 public Object[] find(String s,Integer init) throws LuanException {
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
37 int start = StringLuan.start(s,init,0);
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
38 Matcher m = pattern.matcher(s);
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
39 if( !m.find(start) )
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
40 return null;
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
41 int n = m.groupCount();
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
42 Object[] rtn = new Object[2+n];
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
43 rtn[0] = m.start() + 1;
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
44 rtn[1] = m.end();
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
45 for( int i=0; i<n; i++ ) {
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
46 rtn[2+i] = m.group(i+1);
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
47 }
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
48 return rtn;
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
49 }
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
50
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
51 public LuanFunction gmatch(String s) throws LuanException {
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
52 Utils.checkNotNull(s);
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
53 final Matcher m = pattern.matcher(s);
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
54 return new LuanFunction() {
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
55 @Override public Object call(Luan luan,Object[] args) {
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
56 if( !m.find() )
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
57 return null;
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
58 final int n = m.groupCount();
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
59 if( n == 0 )
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
60 return m.group();
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
61 String[] rtn = new String[n];
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
62 for( int i=0; i<n; i++ ) {
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
63 rtn[i] = m.group(i+1);
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
64 }
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
65 return rtn;
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
66 }
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
67 };
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
68 }
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
69
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
70 public Object[] gsub(Luan luan,String s,Object repl,Integer n) throws LuanException {
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
71 Utils.checkNotNull(s);
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
72 int max = n==null ? Integer.MAX_VALUE : n;
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
73 final Matcher m = pattern.matcher(s);
1777
e59349d53fec optimize String.replace and regex.gsub
Franklin Schmidt <fschmidt@gmail.com>
parents: 1719
diff changeset
74 if( max <= 0 || !m.find() )
e59349d53fec optimize String.replace and regex.gsub
Franklin Schmidt <fschmidt@gmail.com>
parents: 1719
diff changeset
75 return new Object[]{ s, 0 };
1716
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
76 if( repl instanceof String ) {
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
77 String replacement = (String)repl;
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
78 int i = 0;
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
79 StringBuffer sb = new StringBuffer();
1777
e59349d53fec optimize String.replace and regex.gsub
Franklin Schmidt <fschmidt@gmail.com>
parents: 1719
diff changeset
80 do {
1716
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
81 m.appendReplacement(sb,replacement);
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
82 i++;
1777
e59349d53fec optimize String.replace and regex.gsub
Franklin Schmidt <fschmidt@gmail.com>
parents: 1719
diff changeset
83 } while( i<max && m.find() );
1716
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
84 m.appendTail(sb);
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
85 return new Object[]{ sb.toString(), i };
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
86 }
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
87 if( repl instanceof LuanTable ) {
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
88 LuanTable t = (LuanTable)repl;
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
89 int i = 0;
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
90 StringBuffer sb = new StringBuffer();
1777
e59349d53fec optimize String.replace and regex.gsub
Franklin Schmidt <fschmidt@gmail.com>
parents: 1719
diff changeset
91 do {
1716
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
92 String match = m.groupCount()==0 ? m.group() : m.group(1);
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
93 Object val = t.get(luan,match);
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
94 if( val != null ) {
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
95 String replacement = luan.luanToString(val);
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
96 m.appendReplacement(sb,replacement);
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
97 }
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
98 i++;
1777
e59349d53fec optimize String.replace and regex.gsub
Franklin Schmidt <fschmidt@gmail.com>
parents: 1719
diff changeset
99 } while( i<max && m.find() );
1716
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
100 m.appendTail(sb);
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
101 return new Object[]{ sb.toString(), i };
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
102 }
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
103 if( repl instanceof LuanFunction ) {
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
104 LuanFunction fn = (LuanFunction)repl;
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
105 int i = 0;
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
106 StringBuffer sb = new StringBuffer();
1777
e59349d53fec optimize String.replace and regex.gsub
Franklin Schmidt <fschmidt@gmail.com>
parents: 1719
diff changeset
107 do {
1716
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
108 Object[] args;
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
109 final int count = m.groupCount();
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
110 if( count == 0 ) {
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
111 args = new String[]{m.group()};
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
112 } else {
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
113 args = new String[count];
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
114 for( int j=0; j<count; j++ ) {
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
115 args[j] = m.group(j+1);
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
116 }
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
117 }
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
118 Object val = Luan.first( fn.call(luan,args) );
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
119 if( val != null ) {
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
120 String replacement = luan.luanToString(val);
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
121 m.appendReplacement(sb,replacement);
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
122 }
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
123 i++;
1777
e59349d53fec optimize String.replace and regex.gsub
Franklin Schmidt <fschmidt@gmail.com>
parents: 1719
diff changeset
124 } while( i<max && m.find() );
1716
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
125 m.appendTail(sb);
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
126 return new Object[]{ sb.toString(), i };
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
127 }
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
128 throw new LuanException( "bad argument #3 to 'gsub' (string/function/table expected)" );
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
129 }
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
130
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
131 public String[] match(String s,Integer init) throws LuanException {
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
132 int start = StringLuan.start(s,init,0);
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
133 Matcher m = pattern.matcher(s);
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
134 if( !m.find(start) )
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
135 return null;
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
136 int n = m.groupCount();
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
137 if( n == 0 )
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
138 return new String[]{m.group()};
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
139 String[] rtn = new String[n];
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
140 for( int i=0; i<n; i++ ) {
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
141 rtn[i] = m.group(i+1);
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
142 }
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
143 return rtn;
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
144 }
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
145
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
146 public boolean matches(String s) {
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
147 return pattern.matcher(s).find();
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
148 }
1719
2f3a8f16f583 add regex.split
Franklin Schmidt <fschmidt@gmail.com>
parents: 1716
diff changeset
149
2f3a8f16f583 add regex.split
Franklin Schmidt <fschmidt@gmail.com>
parents: 1716
diff changeset
150 public String[] split(String s,Integer limit) throws LuanException {
2f3a8f16f583 add regex.split
Franklin Schmidt <fschmidt@gmail.com>
parents: 1716
diff changeset
151 Utils.checkNotNull(s);
2f3a8f16f583 add regex.split
Franklin Schmidt <fschmidt@gmail.com>
parents: 1716
diff changeset
152 int n = limit==null ? -1 : limit;
2f3a8f16f583 add regex.split
Franklin Schmidt <fschmidt@gmail.com>
parents: 1716
diff changeset
153 return pattern.split(s,n);
2f3a8f16f583 add regex.split
Franklin Schmidt <fschmidt@gmail.com>
parents: 1716
diff changeset
154 }
1716
b82767112d8e add String.regex
Franklin Schmidt <fschmidt@gmail.com>
parents:
diff changeset
155 }