diff 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
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/luan/modules/RegexLuan.java	Sun Jul 24 23:43:03 2022 -0600
@@ -0,0 +1,147 @@
+package luan.modules;
+
+import java.util.regex.Pattern;
+import java.util.regex.Matcher;
+import luan.Luan;
+import luan.LuanMutable;
+import luan.LuanTable;
+import luan.LuanFunction;
+import luan.LuanException;
+
+
+public final class RegexLuan implements LuanMutable {
+	public Pattern pattern;
+	private boolean immutable = false;
+
+	public RegexLuan(String s) {
+		this.pattern = Pattern.compile(s);
+	}
+
+	@Override public boolean isImmutable() {
+		return immutable;
+	}
+
+	@Override public void makeImmutable() {
+		if(immutable)
+			return;
+		immutable = true;
+	}
+
+	public void set(String s) throws LuanException {
+		if( immutable )
+			throw new LuanException("regex is immutable");
+		this.pattern = Pattern.compile(s);
+	}
+
+	public Object[] find(String s,Integer init) throws LuanException {
+		int start = StringLuan.start(s,init,0);
+		Matcher m = pattern.matcher(s);
+		if( !m.find(start) )
+			return null;
+		int n = m.groupCount();
+		Object[] rtn = new Object[2+n];
+		rtn[0] = m.start() + 1;
+		rtn[1] = m.end();
+		for( int i=0; i<n; i++ ) {
+			rtn[2+i] = m.group(i+1);
+		}
+		return rtn;
+	}
+
+	public LuanFunction gmatch(String s) throws LuanException {
+		Utils.checkNotNull(s);
+		final Matcher m = pattern.matcher(s);
+		return new LuanFunction() {
+			@Override public Object call(Luan luan,Object[] args) {
+				if( !m.find() )
+					return null;
+				final int n = m.groupCount();
+				if( n == 0 )
+					return m.group();
+				String[] rtn = new String[n];
+				for( int i=0; i<n; i++ ) {
+					rtn[i] = m.group(i+1);
+				}
+				return rtn;
+			}
+		};
+	}
+
+	public Object[] gsub(Luan luan,String s,Object repl,Integer n) throws LuanException {
+		Utils.checkNotNull(s);
+		int max = n==null ? Integer.MAX_VALUE : n;
+		final Matcher m = pattern.matcher(s);
+		if( repl instanceof String ) {
+			String replacement = (String)repl;
+			int i = 0;
+			StringBuffer sb = new StringBuffer();
+			while( i<max && m.find() ) {
+				m.appendReplacement(sb,replacement);
+				i++;
+			}
+			m.appendTail(sb);
+			return new Object[]{ sb.toString(), i };
+		}
+		if( repl instanceof LuanTable ) {
+			LuanTable t = (LuanTable)repl;
+			int i = 0;
+			StringBuffer sb = new StringBuffer();
+			while( i<max && m.find() ) {
+				String match = m.groupCount()==0 ? m.group() : m.group(1);
+				Object val = t.get(luan,match);
+				if( val != null ) {
+					String replacement = luan.luanToString(val);
+					m.appendReplacement(sb,replacement);
+				}
+				i++;
+			}
+			m.appendTail(sb);
+			return new Object[]{ sb.toString(), i };
+		}
+		if( repl instanceof LuanFunction ) {
+			LuanFunction fn = (LuanFunction)repl;
+			int i = 0;
+			StringBuffer sb = new StringBuffer();
+			while( i<max && m.find() ) {
+				Object[] args;
+				final int count = m.groupCount();
+				if( count == 0 ) {
+					args = new String[]{m.group()};
+				} else {
+					args = new String[count];
+					for( int j=0; j<count; j++ ) {
+						args[j] = m.group(j+1);
+					}
+				}
+				Object val = Luan.first( fn.call(luan,args) );
+				if( val != null ) {
+					String replacement = luan.luanToString(val);
+					m.appendReplacement(sb,replacement);
+				}
+				i++;
+			}
+			m.appendTail(sb);
+			return new Object[]{ sb.toString(), i };
+		}
+		throw new LuanException( "bad argument #3 to 'gsub' (string/function/table expected)" );
+	}
+
+	public String[] match(String s,Integer init) throws LuanException {
+		int start = StringLuan.start(s,init,0);
+		Matcher m = pattern.matcher(s);
+		if( !m.find(start) )
+			return null;
+		int n = m.groupCount();
+		if( n == 0 )
+			return new String[]{m.group()};
+		String[] rtn = new String[n];
+		for( int i=0; i<n; i++ ) {
+			rtn[i] = m.group(i+1);
+		}
+		return rtn;
+	}
+
+	public boolean matches(String s) {
+		return pattern.matcher(s).find();
+	}
+}