📄 stringutils.java
字号:
// Copyright (c) 2001, 2003 Per M.A. Bothner and Brainfood Inc.// This is free software; for terms and warranty disclaimer see ./COPYING.package gnu.xquery.util;import gnu.lists.*;import gnu.math.*;import gnu.mapping.*;import gnu.xml.TextUtils;import gnu.kawa.xml.KNode;import gnu.kawa.xml.UntypedAtomic;/* #ifdef use:java.util.regex */import java.util.regex.Pattern;import java.util.regex.Matcher;/* #endif */import gnu.text.*;/* #ifdef use:java.text.Normalizer */// import java.text.Normalizer;/* #endif */public class StringUtils{ private static String ERROR_VALUE = "<error>"; static String coerceToString (Object arg, String functionName, int iarg, String onEmpty) { if (arg instanceof KNode) arg = KNode.atomicValue(arg); if ((arg == Values.empty || arg == null) && onEmpty != ERROR_VALUE) return onEmpty; if (arg instanceof UntypedAtomic /* #ifdef use:java.lang.CharSequence */ || arg instanceof CharSequence /* #else */ // || arg instanceof String /* #endif */ /* #ifdef use:java.net.URI */ || arg instanceof java.net.URI /* #endif */ || arg instanceof Path) return arg.toString(); throw new WrongType(functionName, iarg, arg, onEmpty == ERROR_VALUE ? "xs:string" : "xs:string?"); } public static Object lowerCase (Object node) { return coerceToString(node, "lower-case", 1, "").toLowerCase(); } public static Object upperCase (Object node) { return coerceToString(node, "upper-case", 1, "").toUpperCase(); } static double asDouble (Object value) { if (! (value instanceof Number)) value = NumberValue.numberValue(value); return ((Number) value).doubleValue(); } public static Object substring (Object str, Object start) { double d1 = asDouble(start); if (Double.isNaN(d1)) return ""; int i = (int) (d1 - 0.5); if (i < 0) i = 0; String s = coerceToString(str, "substring", 1, ""); int len = s.length(); int offset = 0; while (--i >= 0) { if (offset >= len) return ""; char ch = s.charAt(offset++); if (ch >= 0xD800 && ch < 0xDC00 && offset < len) offset++; } return s.substring(offset); } public static Object substring (Object str, Object start, Object length) { String s = coerceToString(str, "substring", 1, ""); int len = s.length(); // Don't use Math.round because it returns 0 given NaN! // We pre-subtract 1 before rounding. double d1 = Math.floor(asDouble(start)-0.5); double d2 = d1 + Math.floor(asDouble(length)+0.5); if (d1 <= 0) d1 = 0; if (d2 > len) d2 = len; if (d2 <= d1) // Including the case where either is NaN. return ""; int i1 = (int) d1; int i2 = (int) d2 - i1; int offset = 0; while (--i1 >= 0) { if (offset >= len) return ""; char ch = s.charAt(offset++); if (ch >= 0xD800 && ch < 0xDC00 && offset < len) offset++; } i1 = offset; while (--i2 >= 0) { if (offset >= len) return ""; char ch = s.charAt(offset++); if (ch >= 0xD800 && ch < 0xDC00 && offset < len) offset++; } i2 = offset; return s.substring(i1, i2); } public static Object stringLength (Object str) { String s = coerceToString(str, "string-length", 1, ""); int slen = s.length(); int len = 0; for (int i = 0; i < slen; ) { char ch = s.charAt(i++); if (ch >= 0xD800 && ch < 0xDC00 && i < slen) i++; len++; } return IntNum.make(len); } public static Object substringBefore (Object str, Object find) { String s = coerceToString(str, "substring-before", 1, ""); String f = coerceToString(find, "substring-before", 2, ""); int flen = f.length(); if (flen==0) return ""; int start = s.indexOf(f); return start >= 0 ? s.substring(0,start) : ""; } public static Object substringAfter (Object str, Object find) { String s = coerceToString(str, "substring-after", 1, ""); String f = coerceToString(find, "substring-after", 2, ""); int flen = f.length(); if (flen==0) return s; int start = s.indexOf(f); return start >= 0 ? s.substring(start+flen) : ""; } public static Object translate (Object str, Object map, Object trans) { String sv = coerceToString(str, "translate", 1, ""); map = KNode.atomicValue(map); if (! (map instanceof UntypedAtomic || map instanceof String)) throw new WrongType("translate", 2, str, "xs:string"); String m = map.toString(); int mlen = m.length(); trans = KNode.atomicValue(trans); if (! (trans instanceof UntypedAtomic || trans instanceof String)) throw new WrongType("translate", 3, str, "xs:string"); String t = trans.toString(); if (mlen==0) return sv; int slen = sv.length(); StringBuffer s = new StringBuffer(slen); int tlen = t.length(); mainLoop: for (int i=0; i < slen;) { char c1 = sv.charAt(i++); char c2 = 0; if (c1 >= 0xD800 && c1 < 0xDC00 && i < slen) c2 = sv.charAt(i++); int j = 0; for (int mi = 0; mi < mlen; ) { char m1 = m.charAt(mi++); char m2 = 0; if (m1 >= 0xD800 && m1 < 0xDC00 && mi < mlen) m2 = m.charAt(mi++); if (m1 == c1 && m2 == c2) { for (int ti = 0; ; j--) { if (ti >= tlen) continue mainLoop; char t1 = t.charAt(ti++); char t2 = 0; if (t1 >= 0xD800 && t1 < 0xDC00 && ti < tlen) t2 = t.charAt(ti++); if (j == 0) { c1 = t1; c2 = t2; break; } } break; } j++; } s.append(c1); if (c2 != 0) s.append(c2); } return s.toString(); } public static Object stringPad (Object str, Object padcount) { int count = ((Number) NumberValue.numberValue(padcount)).intValue(); if (count <= 0) { if (count == 0) return ""; throw new IndexOutOfBoundsException("Invalid string-pad count"); } String sv = coerceToString(str, "string-pad", 1, ""); int slen = sv.length(); StringBuffer s = new StringBuffer(count*slen); for (int i=0; i<count; i++) s.append(sv); return s.toString(); } public static Object contains (Object str, Object contain) { String s = coerceToString(str, "contains", 1, ""); String c = coerceToString(contain, "contains", 2, ""); return s.indexOf(c) <0 ? Boolean.FALSE : Boolean.TRUE; } public static Object startsWith (Object str, Object with) { String s = coerceToString(str, "starts-with", 1, ""); String w = coerceToString(with, "starts-with", 2, ""); return s.startsWith(w) ? Boolean.TRUE : Boolean.FALSE; } public static Object endsWith (Object str, Object with) { String s = coerceToString(str, "ends-with", 1, ""); String w = coerceToString(with, "ends-with", 2, ""); return s.endsWith(w) ? Boolean.TRUE : Boolean.FALSE; } public static Object stringJoin (Object strseq, Object join) { StringBuffer s = new StringBuffer(); String glue = coerceToString(join, "string-join", 2, ERROR_VALUE); int glen = glue.length(); int index=0; boolean started = false; while((index=Values.nextIndex(strseq, index)) >= 0) { Object obj = Values.nextValue(strseq, index-1); if (obj == Values.empty) continue; if (started && glen > 0) s.append(glue); s.append(TextUtils.stringValue(obj)); started=true; } return s.toString(); } public static String concat$V (Object arg1, Object arg2, Object[] args) { arg1 = SequenceUtils.coerceToZeroOrOne(arg1, "concat", 1); String str1 = TextUtils.stringValue(arg1); arg2 = SequenceUtils.coerceToZeroOrOne(arg2, "concat", 2); String str2 = TextUtils.stringValue(arg2);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -