Mercurial Hosting > luan
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(); + } +}