comparison src/luan/modules/StringLuan.java @ 775:1a68fc55a80c

simplify dir structure
author Franklin Schmidt <fschmidt@gmail.com>
date Fri, 26 Aug 2016 14:36:40 -0600
parents core/src/luan/modules/StringLuan.java@e1dfeddfbc7b
children 9a57f0b16c2b
comparison
equal deleted inserted replaced
774:3e30cf310e56 775:1a68fc55a80c
1 package luan.modules;
2
3 import java.util.Arrays;
4 import java.util.regex.Pattern;
5 import java.util.regex.Matcher;
6 import luan.Luan;
7 import luan.LuanState;
8 import luan.LuanTable;
9 import luan.LuanFunction;
10 import luan.LuanException;
11 import luan.LuanMethod;
12
13
14 public final class StringLuan {
15
16 static int start(String s,int i) {
17 int len = s.length();
18 return i==0 ? 0 : i > 0 ? Math.min(i-1,len) : Math.max(len+i,0);
19 }
20
21 static int start(String s,Integer i,int dflt) {
22 return i==null ? dflt : start(s,i);
23 }
24
25 static int end(String s,int i) {
26 int len = s.length();
27 return i==0 ? 0 : i > 0 ? Math.min(i,len) : Math.max(len+i+1,0);
28 }
29
30 static int end(String s,Integer i,int dflt) {
31 return i==null ? dflt : end(s,i);
32 }
33
34 @LuanMethod public static Integer[] unicode(String s,Integer i,Integer j) throws LuanException {
35 Utils.checkNotNull(s);
36 int start = start(s,i,1);
37 int end = end(s,j,start+1);
38 Integer[] chars = new Integer[end-start];
39 for( int k=0; k<chars.length; k++ ) {
40 chars[k] = (int)s.charAt(start+k);
41 }
42 return chars;
43 }
44
45 public static String char_(int... chars) {
46 char[] a = new char[chars.length];
47 for( int i=0; i<chars.length; i++ ) {
48 a[i] = (char)chars[i];
49 }
50 return new String(a);
51 }
52
53 @LuanMethod public static byte[] to_binary(String s) {
54 return s.getBytes();
55 }
56
57 public static String lower(String s) throws LuanException {
58 Utils.checkNotNull(s);
59 return s.toLowerCase();
60 }
61
62 public static String upper(String s) throws LuanException {
63 Utils.checkNotNull(s);
64 return s.toUpperCase();
65 }
66
67 public static String trim(String s) throws LuanException {
68 Utils.checkNotNull(s);
69 return s.trim();
70 }
71
72 public static String reverse(String s) throws LuanException {
73 Utils.checkNotNull(s);
74 return new StringBuilder(s).reverse().toString();
75 }
76
77 public static String rep(String s,int n,String sep) {
78 if( n < 1 )
79 return "";
80 StringBuilder buf = new StringBuilder(s);
81 while( --n > 0 ) {
82 if( sep != null )
83 buf.append(sep);
84 buf.append(s);
85 }
86 return buf.toString();
87 }
88
89 public static String sub(String s,int i,Integer j) throws LuanException {
90 Utils.checkNotNull(s);
91 int start = start(s,i);
92 int end = end(s,j,s.length());
93 return s.substring(start,end);
94 }
95
96 @LuanMethod public static Object[] find(String s,String pattern,Integer init,Boolean plain) {
97 int start = start(s,init,0);
98 if( Boolean.TRUE.equals(plain) ) {
99 int i = s.indexOf(pattern,start);
100 return i == -1 ? null : new Integer[]{i+1,i+pattern.length()};
101 }
102 Matcher m = Pattern.compile(pattern).matcher(s);
103 if( !m.find(start) )
104 return null;
105 int n = m.groupCount();
106 Object[] rtn = new Object[2+n];
107 rtn[0] = m.start() + 1;
108 rtn[1] = m.end();
109 for( int i=0; i<n; i++ ) {
110 rtn[2+i] = m.group(i+1);
111 }
112 return rtn;
113 }
114
115 @LuanMethod public static String[] match(String s,String pattern,Integer init) {
116 int start = start(s,init,0);
117 Matcher m = Pattern.compile(pattern).matcher(s);
118 if( !m.find(start) )
119 return null;
120 int n = m.groupCount();
121 if( n == 0 )
122 return new String[]{m.group()};
123 String[] rtn = new String[n];
124 for( int i=0; i<n; i++ ) {
125 rtn[i] = m.group(i+1);
126 }
127 return rtn;
128 }
129
130 public static LuanFunction gmatch(String s,String pattern) throws LuanException {
131 Utils.checkNotNull(s);
132 final Matcher m = Pattern.compile(pattern).matcher(s);
133 return new LuanFunction() {
134 @Override public Object call(LuanState luan,Object[] args) {
135 if( !m.find() )
136 return null;
137 final int n = m.groupCount();
138 if( n == 0 )
139 return m.group();
140 String[] rtn = new String[n];
141 for( int i=0; i<n; i++ ) {
142 rtn[i] = m.group(i+1);
143 }
144 return rtn;
145 }
146 };
147 }
148
149 @LuanMethod public static Object[] gsub(LuanState luan,String s,String pattern,Object repl,Integer n) throws LuanException {
150 Utils.checkNotNull(s);
151 int max = n==null ? Integer.MAX_VALUE : n;
152 final Matcher m = Pattern.compile(pattern).matcher(s);
153 if( repl instanceof String ) {
154 String replacement = (String)repl;
155 int i = 0;
156 StringBuffer sb = new StringBuffer();
157 while( i<max && m.find() ) {
158 m.appendReplacement(sb,replacement);
159 i++;
160 }
161 m.appendTail(sb);
162 return new Object[]{ sb.toString(), i };
163 }
164 if( repl instanceof LuanTable ) {
165 LuanTable t = (LuanTable)repl;
166 int i = 0;
167 StringBuffer sb = new StringBuffer();
168 while( i<max && m.find() ) {
169 String match = m.groupCount()==0 ? m.group() : m.group(1);
170 Object val = t.get(luan,match);
171 if( val != null ) {
172 String replacement = luan.toString(val);
173 m.appendReplacement(sb,replacement);
174 }
175 i++;
176 }
177 m.appendTail(sb);
178 return new Object[]{ sb.toString(), i };
179 }
180 if( repl instanceof LuanFunction ) {
181 LuanFunction fn = (LuanFunction)repl;
182 int i = 0;
183 StringBuffer sb = new StringBuffer();
184 while( i<max && m.find() ) {
185 Object[] args;
186 final int count = m.groupCount();
187 if( count == 0 ) {
188 args = new String[]{m.group()};
189 } else {
190 args = new String[count];
191 for( int j=0; j<count; j++ ) {
192 args[j] = m.group(j+1);
193 }
194 }
195 Object val = Luan.first( fn.call(luan,args) );
196 if( val != null ) {
197 String replacement = luan.toString(val);
198 m.appendReplacement(sb,replacement);
199 }
200 i++;
201 }
202 m.appendTail(sb);
203 return new Object[]{ sb.toString(), i };
204 }
205 throw new LuanException( "bad argument #3 to 'gsub' (string/function/table expected)" );
206 }
207
208 // note - String.format() is too stupid to convert between ints and floats.
209 public static String format(String format,Object... args) {
210 return String.format(format,args);
211 }
212
213 public static String concat(LuanState luan,Object... args) throws LuanException {
214 StringBuilder sb = new StringBuilder();
215 for( Object arg : args ) {
216 sb.append( luan.toString(arg) );
217 }
218 return sb.toString();
219 }
220
221 public static String encode(String s) {
222 return Luan.stringEncode(s);
223 }
224
225 public static Number to_number(String s,Integer base) throws LuanException {
226 Utils.checkNotNull(s);
227 try {
228 if( base == null ) {
229 return Double.valueOf(s);
230 } else {
231 return Long.valueOf(s,base);
232 }
233 } catch(NumberFormatException e) {}
234 return null;
235 }
236
237 public static boolean matches(String s,String pattern) throws LuanException {
238 Utils.checkNotNull(s);
239 return Pattern.compile(pattern).matcher(s).find();
240 }
241
242 public static LuanTable split(String s,String pattern) throws LuanException {
243 Utils.checkNotNull(s);
244 return new LuanTable(Arrays.asList(s.split(pattern)));
245 }
246
247 }