comparison src/luan/modules/RegexLuan.java @ 1716:b82767112d8e

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