1
0
mirror of https://github.com/gnosygnu/xowa.git synced 2026-03-02 03:49:30 +00:00
This commit is contained in:
gnosygnu
2015-07-21 19:52:26 -04:00
parent 99f9c3ccea
commit 9d63f03b3d
31 changed files with 381 additions and 446 deletions

View File

@@ -15,40 +15,19 @@ GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.texts; import gplx.*;
package gplx.core.regxs; import gplx.*; import gplx.core.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegxAdp {
void Under_sync() {
try {under = Pattern.compile(pattern, Pattern.DOTALL | Pattern.UNICODE_CHARACTER_CLASS);} // JRE.7:UNICODE_CHARACTER_CLASS; added during %w fix for en.w:A#; DATE:2015-06-10
catch (Exception e) { // NOTE: if invalid, then default to empty pattern (which should return nothing); EX:d:〆る generates [^]; DATE:2013-10-20
pattern_is_invalid = true;
under = Pattern.compile("", Pattern.DOTALL | Pattern.UNICODE_CHARACTER_CLASS);
}
} private Pattern under;
public RegxMatch Match(String input, int bgn) {
Matcher match = under.matcher(input);
boolean success = match.find(bgn);
int match_bgn = success ? match.start() : String_.Find_none;
int match_end = success ? match.end() : String_.Find_none;
RegxGroup[] ary = RegxGroup.Ary_empty;
int groups_len = match.groupCount();
if (success && groups_len > 0) {
ary = new RegxGroup[groups_len];
for (int i = 0; i < groups_len; i++)
ary[i] = new RegxGroup(true, match.start(i + 1), match.end(i + 1), match.group(i + 1));
}
return new RegxMatch(success, match_bgn, match_end, ary);
}
public String ReplaceAll(String input, String replace) {return under.matcher(input).replaceAll(replace);}
public String Pattern() {return pattern;} public RegxAdp Pattern_(String val) {pattern = val; Under_sync(); return this;} private String pattern;
public class Regx_adp {
@gplx.Internal protected Regx_adp(String regx) {Pattern_(regx);}
public String Pattern() {return pattern;} public Regx_adp Pattern_(String val) {pattern = val; Under_sync(); return this;} private String pattern;
public boolean Pattern_is_invalid() {return pattern_is_invalid;} private boolean pattern_is_invalid = false;
public RegxMatch[] Match_all(String text, int bgn) {
public Regx_match[] Match_all(String text, int bgn) {
int idx = bgn;
List_adp rv = List_adp_.new_();
int len = String_.Len(text);
while (idx <= len) { // NOTE: must be <= not < else "a?" will return null instead of ""; PAGE:en.d:; DATE:2015-01-30
RegxMatch match = this.Match(text, idx);
Regx_match match = this.Match(text, idx);
if (match.Rslt_none()) break;
rv.Add(match);
int find_bgn = match.Find_bgn();
@@ -58,7 +37,29 @@ public class RegxAdp {
: find_bgn + find_len // otherwise search after find_end
;
}
return (RegxMatch[])rv.To_ary(RegxMatch.class);
return (Regx_match[])rv.To_ary(Regx_match.class);
}
private Pattern under;
void Under_sync() {
try {under = Pattern.compile(pattern, Pattern.DOTALL | Pattern.UNICODE_CHARACTER_CLASS);} // JRE.7:UNICODE_CHARACTER_CLASS; added during %w fix for en.w:A#; DATE:2015-06-10
catch (Exception e) { // NOTE: if invalid, then default to empty pattern (which should return nothing); EX:d:〆る generates [^]; DATE:2013-10-20
pattern_is_invalid = true;
under = Pattern.compile("", Pattern.DOTALL | Pattern.UNICODE_CHARACTER_CLASS);
}
}
public Regx_match Match(String input, int bgn) {
Matcher match = under.matcher(input);
boolean success = match.find(bgn);
int match_bgn = success ? match.start() : String_.Find_none;
int match_end = success ? match.end() : String_.Find_none;
Regx_group[] ary = Regx_group.Ary_empty;
int groups_len = match.groupCount();
if (success && groups_len > 0) {
ary = new Regx_group[groups_len];
for (int i = 0; i < groups_len; i++)
ary[i] = new Regx_group(true, match.start(i + 1), match.end(i + 1), match.group(i + 1));
}
return new Regx_match(success, match_bgn, match_end, ary);
}
public String ReplaceAll(String input, String replace) {return under.matcher(input).replaceAll(replace);}
}
@gplx.Internal protected RegxAdp(String regx) {Pattern_(regx);}
}

View File

@@ -15,16 +15,15 @@ GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.texts; import gplx.*;
public class RegxAdp_mpo_find {
public String Input() {return input;} public RegxAdp_mpo_find Input_(String val) {input = val; return this;} private String input;
public String Find() {return find;} public RegxAdp_mpo_find Find_(String val) {find = val; return this;} private String find;
public List_adp Exec_asList() {
RegxAdp regx = RegxAdp_.new_(find);
package gplx.core.regxs; import gplx.*; import gplx.core.*;
public class Regx_adp_ {
public static Regx_adp new_(String pattern) {return new Regx_adp(pattern);}
public static List_adp Find_all(String input, String find) {
Regx_adp regx = Regx_adp_.new_(find);
int idx = 0;
List_adp rv = List_adp_.new_();
while (true) {
RegxMatch match = regx.Match(input, idx);
Regx_match match = regx.Match(input, idx);
if (match.Rslt_none()) break;
rv.Add(match);
int findBgn = match.Find_bgn();
@@ -33,4 +32,12 @@ public class RegxAdp_mpo_find {
}
return rv;
}
public static String Replace(String raw, String regx_str, String replace) {
Regx_adp regx = Regx_adp_.new_(regx_str);
return regx.ReplaceAll(raw, replace);
}
public static boolean Match(String input, String pattern) {
Regx_adp rv = new Regx_adp(pattern);
return rv.Match(input, 0).Rslt();
}
}

View File

@@ -15,36 +15,36 @@ GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.texts; import gplx.*;
package gplx.core.regxs; import gplx.*; import gplx.core.*;
import org.junit.*;
public class RegxAdp__tst implements TfdsEqListItmStr {
public class Regx_adp__tst implements TfdsEqListItmStr {
@Test public void Match() {
tst_Match("a", "a", true); // basic
tst_Match("a", "b", false); // matchNot
tst_Match("a", "ab", true); // matchPart
tst_Match("a\\+b", "a+b", true); // matchEscape
tst_Match("[^a]", "b", true); // charSet_negate
} void tst_Match(String find, String input, boolean expd) {Tfds.Eq(expd, RegxAdp_.Match(input, find));}
} void tst_Match(String find, String input, boolean expd) {Tfds.Eq(expd, Regx_adp_.Match(input, find));}
@Test public void Match_all() {
tst_Match_all("#REDIRECT [[Template:Error]]", "^\\p{Nd}*", 1); // handle match = true but len = 0; DATE:2013-04-11
tst_Match_all("a", "$", 1); // $ should match once, not zero; DATE:2014-09-02
} void tst_Match_all(String input, String regx, int expd) {Tfds.Eq(expd, RegxAdp_.new_(regx).Match_all(input, 0).length);}
} void tst_Match_all(String input, String regx, int expd) {Tfds.Eq(expd, Regx_adp_.new_(regx).Match_all(input, 0).length);}
@Test public void Replace() {
tst_Replace("ab", "a", "b", "bb"); // basic
tst_Replace("ab", "c", "b", "ab"); // replaceNot
tst_Replace("aba", "a", "b", "bbb"); // replaceMultiple
} void tst_Replace(String input, String find, String replace, String expd) {Tfds.Eq(expd, RegxAdp_.Replace(input, find, replace));}
} void tst_Replace(String input, String find, String replace, String expd) {Tfds.Eq(expd, Regx_adp_.Replace(input, find, replace));}
@Test public void Match_WholeWord() {
tst_WholeWord("a", "ab a", true); // pass a
tst_WholeWord("a", "ab c", false); // fail ab
tst_WholeWord("a", "a_", false); // fail a_
tst_WholeWord("[a]", "a [a] c", true); // pass [a]
tst_WholeWord("[a]", "a[a]c", false); // fail a[a]c
} void tst_WholeWord(String regx, String text, boolean expd) {Tfds.Eq(expd, RegxAdp_.Match(text, RegxBldr.WholeWord(regx)));}
} void tst_WholeWord(String regx, String text, boolean expd) {Tfds.Eq(expd, Regx_adp_.Match(text, Regx_bldr.WholeWord(regx)));}
@Test public void Match_As() {
tst_Regx("public static [A-Za-z0-9_]+ as_\\(Object obj\\)", "public static Obj1 as_(Object obj) {return obj instanceof Obj1 ? (Obj1)obj : null;}", true);
tst_Regx("public static [A-Za-z0-9_]+ as_\\(Object obj\\)", "public static boolean Asterisk(Object obj) {}", false);
} void tst_Regx(String regx, String text, boolean expd) {Tfds.Eq(expd, RegxAdp_.Match(text, regx));}
} void tst_Regx(String regx, String text, boolean expd) {Tfds.Eq(expd, Regx_adp_.Match(text, regx));}
@Test public void Find() {
tst_Matches("b", "a b c b a", match_(2, 1), match_(6, 1));
tst_Matches("d", "a b c b a");
@@ -53,30 +53,30 @@ public class RegxAdp__tst implements TfdsEqListItmStr {
@Test public void Groups() {
tst_Groups("abc def ghi dz", "(d\\p{L}+)", "def", "dz");
}
RegxMatch[] matches_(int... bgnAry) {
Regx_match[] matches_(int... bgnAry) {
int aryLen = Array_.Len(bgnAry);
RegxMatch[] rv = new RegxMatch[aryLen];
Regx_match[] rv = new Regx_match[aryLen];
for (int i = 0; i < aryLen; i++)
rv[i] = match_(bgnAry[i]);
return rv;
}
RegxMatch match_(int bgn) {return match_(bgn, Int_.MinValue);}
RegxMatch match_(int bgn, int len) {return new RegxMatch(true, bgn, bgn + len, RegxGroup.Ary_empty);}
void tst_Matches(String find, String input, RegxMatch... expd) {
Regx_match match_(int bgn) {return match_(bgn, Int_.MinValue);}
Regx_match match_(int bgn, int len) {return new Regx_match(true, bgn, bgn + len, Regx_group.Ary_empty);}
void tst_Matches(String find, String input, Regx_match... expd) {
List_adp expdList = Array_.XtoList(expd);
List_adp actlList = RegxAdp_.Find_args(input, find).Exec_asList();
List_adp actlList = Regx_adp_.Find_all(input, find);
Tfds.Eq_list(expdList, actlList, this);
}
void tst_Groups(String text, String regx, String... expd) {
RegxAdp regx_mgr = RegxAdp_.new_(regx);
RegxMatch[] rslts = regx_mgr.Match_all(text, 0);
Regx_adp regx_mgr = Regx_adp_.new_(regx);
Regx_match[] rslts = regx_mgr.Match_all(text, 0);
Tfds.Eq_ary_str(expd, To_ary(rslts));
}
String[] To_ary(RegxMatch[] ary) {
String[] To_ary(Regx_match[] ary) {
List_adp rv = List_adp_.new_();
int len = ary.length;
for (int i = 0; i < len; i++) {
RegxMatch itm = ary[i];
Regx_match itm = ary[i];
int cap_len = itm.Groups().length;
for (int j = 0; j < cap_len; j++) {
rv.Add(itm.Groups()[j].Val());
@@ -85,7 +85,7 @@ public class RegxAdp__tst implements TfdsEqListItmStr {
return rv.To_str_ary();
}
public String XtoStr(Object curObj, Object expdObj) {
RegxMatch cur = (RegxMatch)curObj, expd = (RegxMatch)expdObj;
Regx_match cur = (Regx_match)curObj, expd = (Regx_match)expdObj;
String rv = "bgn=" + cur.Find_bgn();
if (expd != null && expd.Find_len() != Int_.MinValue) rv += " len=" + cur.Find_len();
return rv;

View File

@@ -15,11 +15,11 @@ GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.texts; import gplx.*;
package gplx.core.regxs; import gplx.*; import gplx.core.*;
import gplx.core.strings.*;
public class RegxBldr {
public static String Includes(String characters) {return String_.Concat_any(RegxBldr.Tkn_CharSetBegin, characters, RegxBldr.Tkn_CharSetEnd);}
public static String Excludes(String characters) {return String_.Concat_any(RegxBldr.Tkn_CharSetBegin, RegxBldr.Tkn_Not, characters, RegxBldr.Tkn_CharSetEnd);}
public class Regx_bldr {
public static String Includes(String characters) {return String_.Concat_any(Regx_bldr.Tkn_CharSetBegin, characters, Regx_bldr.Tkn_CharSetEnd);}
public static String Excludes(String characters) {return String_.Concat_any(Regx_bldr.Tkn_CharSetBegin, Regx_bldr.Tkn_Not, characters, Regx_bldr.Tkn_CharSetEnd);}
public static String WholeWord(String word) {return String_.Concat_any("(?<![A-Za-z0-9_])", EscapeAll(word), "(?![A-Za-z0-9_])");}
public static String EscapeAll(String text) {
String_bldr sb = String_bldr_.new_();
@@ -27,19 +27,19 @@ public class RegxBldr {
for (int i = 0; i < len; i++) {
char c = String_.CharAt(text, i);
if (RegxChar_chk(c))
sb.Add(RegxBldr.Tkn_Escape);
sb.Add(Regx_bldr.Tkn_Escape);
sb.Add(c);
}
return sb.XtoStr();
}
public static boolean RegxChar_chk(char c) {
return
( c == RegxBldr.Tkn_Escape || c == RegxBldr.Tkn_Or
|| c == RegxBldr.Tkn_LineBegin || c == RegxBldr.Tkn_LineEnd
|| c == RegxBldr.Tkn_GroupBegin || c == RegxBldr.Tkn_GroupEnd
|| c == RegxBldr.Tkn_RepBegin || c == RegxBldr.Tkn_RepEnd
|| c == RegxBldr.Tkn_Wild_0Plus || c == RegxBldr.Tkn_Wild_1Plus || c == RegxBldr.Tkn_Wild_0or1
|| c == RegxBldr.Tkn_CharSetBegin || c == RegxBldr.Tkn_CharSetEnd
( c == Regx_bldr.Tkn_Escape || c == Regx_bldr.Tkn_Or
|| c == Regx_bldr.Tkn_LineBegin || c == Regx_bldr.Tkn_LineEnd
|| c == Regx_bldr.Tkn_GroupBegin || c == Regx_bldr.Tkn_GroupEnd
|| c == Regx_bldr.Tkn_RepBegin || c == Regx_bldr.Tkn_RepEnd
|| c == Regx_bldr.Tkn_Wild_0Plus || c == Regx_bldr.Tkn_Wild_1Plus || c == Regx_bldr.Tkn_Wild_0or1
|| c == Regx_bldr.Tkn_CharSetBegin || c == Regx_bldr.Tkn_CharSetEnd
);
}
public static final char

View File

@@ -15,12 +15,12 @@ GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.texts; import gplx.*;
public class RegxGroup {
public RegxGroup(boolean rslt, int bgn, int end, String val) {this.rslt = rslt; this.bgn = bgn; this.end = end; this.val = val;}
package gplx.core.regxs; import gplx.*; import gplx.core.*;
public class Regx_group {
public Regx_group(boolean rslt, int bgn, int end, String val) {this.rslt = rslt; this.bgn = bgn; this.end = end; this.val = val;}
public boolean Rslt() {return rslt;} private boolean rslt;
public int Bgn() {return bgn;} int bgn;
public int End() {return end;} int end;
public String Val() {return val;} private String val;
public static final RegxGroup[] Ary_empty = new RegxGroup[0];
public static final Regx_group[] Ary_empty = new Regx_group[0];
}

View File

@@ -15,14 +15,14 @@ GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.texts; import gplx.*;
public class RegxMatch {
public RegxMatch(boolean rslt, int find_bgn, int find_end, RegxGroup[] groups) {this.rslt = rslt; this.find_bgn = find_bgn; this.find_end = find_end; this.groups = groups;}
package gplx.core.regxs; import gplx.*; import gplx.core.*;
public class Regx_match {
public Regx_match(boolean rslt, int find_bgn, int find_end, Regx_group[] groups) {this.rslt = rslt; this.find_bgn = find_bgn; this.find_end = find_end; this.groups = groups;}
public boolean Rslt() {return rslt;} private boolean rslt;
public boolean Rslt_none() {return !rslt;} // NOTE: was "|| find_end - find_bgn == 0"; DATE:2013-04-11; DATE:2014-09-02
public int Find_bgn() {return find_bgn;} int find_bgn;
public int Find_end() {return find_end;} int find_end;
public int Find_len() {return find_end - find_bgn;}
public RegxGroup[] Groups() {return groups;} RegxGroup[] groups = RegxGroup.Ary_empty;
public static final RegxMatch[] Ary_empty = new RegxMatch[0];
public Regx_group[] Groups() {return groups;} Regx_group[] groups = Regx_group.Ary_empty;
public static final Regx_match[] Ary_empty = new Regx_match[0];
}

View File

@@ -1,28 +0,0 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.texts; import gplx.*;
public class RegxAdp_ {
public static RegxAdp_mpo_find Find_args(String input, String find) {return new RegxAdp_mpo_find().Input_(input).Find_(find);}
public static RegxAdp_mpo_replace Replace_args(String input, String find, String replace) {return new RegxAdp_mpo_replace().Input_(input).Find_(find).Replace_(replace);}
public static RegxAdp new_(String pattern) {return new RegxAdp(pattern);}
public static String Replace(String raw, String regx, String replace) {return Replace_args(raw, regx, replace).Exec_asStr();}
public static boolean Match(String input, String pattern) {
RegxAdp rv = new RegxAdp(pattern);
return rv.Match(input, 0).Rslt();
}
}

View File

@@ -1,27 +0,0 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.texts; import gplx.*;
public class RegxAdp_mpo_replace {
public String Input() {return input;} public RegxAdp_mpo_replace Input_(String val) {input = val; return this;} private String input;
public String Find() {return find;} public RegxAdp_mpo_replace Find_(String val) {find = val; return this;} private String find;
public String Replace() {return replace;} public RegxAdp_mpo_replace Replace_(String val) {replace = val; return this;} private String replace;
public String Exec_asStr() {
RegxAdp regx = RegxAdp_.new_(find);
return regx.ReplaceAll(input, replace);
}
}

View File

@@ -16,12 +16,13 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.texts; import gplx.*;
import gplx.core.regxs.*;
public class RegxPatn_cls_ioMatch {
public String Raw() {return raw;} private String raw;
public boolean CaseSensitive() {return caseSensitive;} private boolean caseSensitive;
public boolean Matches(String text) {
text = String_.CaseNormalize(caseSensitive, text);
return RegxAdp_.Match(text, compiled);} // WNT-centric: Io_mgr paths are case-insensitive;
return Regx_adp_.Match(text, compiled);} // WNT-centric: Io_mgr paths are case-insensitive;
@Override public String toString() {return raw;}
String compiled;

View File

@@ -16,7 +16,7 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.texts; import gplx.*;
import gplx.core.strings.*;
import gplx.core.strings.*; import gplx.core.regxs.*;
public class RegxPatn_cls_ioMatch_ {
public static final String Wildcard = "*";
public static final String OrDelimiter = "|";
@@ -32,22 +32,22 @@ public class RegxPatn_cls_ioMatch_ {
if (raw == ImpossiblePath) return ImpossiblePath;
String_bldr sb = String_bldr_.new_();
sb.Add(RegxBldr.Tkn_LineBegin); // Char_LineBegin for exact match (else "LIKE a" would match "abc")
sb.Add(Regx_bldr.Tkn_LineBegin); // Char_LineBegin for exact match (else "LIKE a" would match "abc")
int rawLen = String_.Len(raw);
for (int i = 0; i < rawLen; i++) {
char c = String_.CharAt(raw, i);
if (c == '\\')
sb.Add("\\\\");
else if (c == '*')
sb.Add(".").Add(RegxBldr.Tkn_Wild_0Plus);
sb.Add(".").Add(Regx_bldr.Tkn_Wild_0Plus);
else if (c == '|')
sb.Add(RegxBldr.Tkn_LineEnd).Add("|").Add(RegxBldr.Tkn_LineBegin); // each term must be bracketed by lineBgn/lineEnd; ex: A|B -> ^A$|^B$
sb.Add(Regx_bldr.Tkn_LineEnd).Add("|").Add(Regx_bldr.Tkn_LineBegin); // each term must be bracketed by lineBgn/lineEnd; ex: A|B -> ^A$|^B$
else
sb.Add(c);
}
sb.Add(RegxBldr.Tkn_LineEnd);
sb.Add(Regx_bldr.Tkn_LineEnd);
return sb.XtoStr();
}
public static final String InvalidCharacters = "|*?\"<>"; // : / \ are omitted b/c they will cause full paths to fail
public static final String ValidCharacters = RegxBldr.Excludes(InvalidCharacters);
public static final String ValidCharacters = Regx_bldr.Excludes(InvalidCharacters);
}

View File

@@ -16,10 +16,11 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.texts; import gplx.*;
import gplx.core.regxs.*;
public class RegxPatn_cls_like {
public char Escape() {return escape;} char escape; public static final char EscapeDefault = '|';
public String Raw() {return raw;} private String raw;
public boolean Matches(String text) {return RegxAdp_.Match(text, compiled);}
public boolean Matches(String text) {return Regx_adp_.Match(text, compiled);}
@Override public String toString() {return String_.Format("LIKE {0} ESCAPE {1} -> {2}", raw, escape, compiled);}
String compiled;

View File

@@ -16,7 +16,7 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.texts; import gplx.*;
import gplx.core.strings.*;
import gplx.core.strings.*; import gplx.core.regxs.*;
public class RegxPatn_cls_like_ {
public static RegxPatn_cls_like parse_(String regxRaw, char escape) {
String regx = Compile(regxRaw, escape);
@@ -26,7 +26,7 @@ public class RegxPatn_cls_like_ {
char Wildcard = '%', AnyChar = '_';
boolean insideCharSet = false;
String_bldr sb = String_bldr_.new_();
sb.Add(RegxBldr.Tkn_LineBegin);
sb.Add(Regx_bldr.Tkn_LineBegin);
int rawLen = String_.Len(raw);
for (int i = 0; i < rawLen; i++) {
char c = String_.CharAt(raw, i);
@@ -36,28 +36,28 @@ public class RegxPatn_cls_like_ {
else throw Err_.new_wo_type("escape cannot be last char", "raw", raw, "escape", escape, "i", i);
}
else if (c == Wildcard) { // % -> .*
sb.Add(RegxBldr.Tkn_AnyChar).Add(RegxBldr.Tkn_Wild_0Plus);
sb.Add(Regx_bldr.Tkn_AnyChar).Add(Regx_bldr.Tkn_Wild_0Plus);
}
else if (c == AnyChar) // _ -> .
sb.Add(RegxBldr.Tkn_AnyChar);
else if (c == RegxBldr.Tkn_CharSetBegin) { // toggle insideCharSet for ^
sb.Add(Regx_bldr.Tkn_AnyChar);
else if (c == Regx_bldr.Tkn_CharSetBegin) { // toggle insideCharSet for ^
insideCharSet = true;
sb.Add(c);
}
else if (c == RegxBldr.Tkn_CharSetEnd) { // toggle insideCharSet for ^
else if (c == Regx_bldr.Tkn_CharSetEnd) { // toggle insideCharSet for ^
insideCharSet = false;
sb.Add(c);
}
else if (c == RegxBldr.Tkn_Not && insideCharSet) { // ^ is used for Not in CharSet, but also used for LineStart; do not escape if insideCharSet
else if (c == Regx_bldr.Tkn_Not && insideCharSet) { // ^ is used for Not in CharSet, but also used for LineStart; do not escape if insideCharSet
insideCharSet = false;
sb.Add(c);
}
else if (RegxBldr.RegxChar_chk(c))
sb.Add(RegxBldr.Tkn_Escape).Add(c);
else if (Regx_bldr.RegxChar_chk(c))
sb.Add(Regx_bldr.Tkn_Escape).Add(c);
else // regular text
sb.Add(c);
}
sb.Add(RegxBldr.Tkn_LineEnd);
sb.Add(Regx_bldr.Tkn_LineEnd);
return sb.XtoStr();
}
}

View File

@@ -16,7 +16,7 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.texts; import gplx.*;
import org.junit.*;
import org.junit.*; import gplx.core.regxs.*;
public class RegxPatn_cls_like_tst {
@Test public void Basic() {
tst_Match("abcd", "abcd", true); // basic; pass
@@ -60,17 +60,17 @@ public class RegxPatn_cls_like_tst {
tst_Match("a~b", "a~b", '~', false); // escape char; fail
tst_Match("a~b", "a~~b", '~', true); // escape char; pass
}
@Test public void Chars() { // Escape RegxBldr; ex: LIKE 'a{' -> a\{
tst_EscapeRegxChar(RegxBldr.Tkn_Escape); // \
tst_EscapeRegxChar(RegxBldr.Tkn_GroupBegin); // [
tst_EscapeRegxChar(RegxBldr.Tkn_GroupEnd); // ]
tst_EscapeRegxChar(RegxBldr.Tkn_LineBegin); // ^
tst_EscapeRegxChar(RegxBldr.Tkn_LineEnd); // $
tst_EscapeRegxChar(RegxBldr.Tkn_RepBegin); // {
tst_EscapeRegxChar(RegxBldr.Tkn_RepEnd); // }
tst_EscapeRegxChar(RegxBldr.Tkn_Wild_0or1); // ?
tst_EscapeRegxChar(RegxBldr.Tkn_Wild_0Plus); // *
tst_EscapeRegxChar(RegxBldr.Tkn_Wild_1Plus); // +
@Test public void Chars() { // Escape Regx_bldr; ex: LIKE 'a{' -> a\{
tst_EscapeRegxChar(Regx_bldr.Tkn_Escape); // \
tst_EscapeRegxChar(Regx_bldr.Tkn_GroupBegin); // [
tst_EscapeRegxChar(Regx_bldr.Tkn_GroupEnd); // ]
tst_EscapeRegxChar(Regx_bldr.Tkn_LineBegin); // ^
tst_EscapeRegxChar(Regx_bldr.Tkn_LineEnd); // $
tst_EscapeRegxChar(Regx_bldr.Tkn_RepBegin); // {
tst_EscapeRegxChar(Regx_bldr.Tkn_RepEnd); // }
tst_EscapeRegxChar(Regx_bldr.Tkn_Wild_0or1); // ?
tst_EscapeRegxChar(Regx_bldr.Tkn_Wild_0Plus); // *
tst_EscapeRegxChar(Regx_bldr.Tkn_Wild_1Plus); // +
}
void tst_Match(String raw, String regx, boolean expd) {tst_Match(raw, regx, RegxPatn_cls_like.EscapeDefault, expd);}
void tst_Match(String raw, String regx, char escape, boolean expd) {

View File

@@ -19,6 +19,12 @@ package gplx;
import gplx.core.strings.*; import gplx.core.consoles.*;
public class Tfds { // URL:doc/gplx.tfds/Tfds.txt
public static boolean SkipDb = false;
public static void Eq_bool (boolean expd , boolean actl, String fmt, Object... args) {Eq_str(Bool_.Xto_str_lower(expd), Bool_.Xto_str_lower(actl), fmt, args);}
public static void Eq_str (byte[] expd, String actl, String fmt, Object... args) {Eq_str(String_.new_u8(expd), actl, fmt, args);}
public static void Eq_str (byte[] expd, byte[] actl, String fmt, Object... args) {Eq_str(String_.new_u8(expd), String_.new_u8(actl), fmt, args);}
public static void Eq_str (String expd, byte[] actl, String fmt, Object... args) {Eq_str(expd, String_.new_u8(actl), fmt, args);}
public static void Eq_str (String expd, String actl, String fmt, Object... args) {Eq_wkr(expd, actl, true, String_.Format(fmt, args));}
public static void Eq(Object expd, Object actl) {Eq_wkr(expd, actl, true, EmptyStr);}
public static void Eq_able(EqAble expd, EqAble actl) {Eq_able_wkr(expd, actl, true, EmptyStr);}
public static void Eq_able(EqAble expd, EqAble actl, String fmt, Object... args) {Eq_able_wkr(expd, actl, true, String_.Format(fmt, args));}
@@ -29,10 +35,11 @@ public class Tfds { // URL:doc/gplx.tfds/Tfds.txt
public static void Eq_date(DateAdp expd, DateAdp actl) {Eq_wkr(expd.XtoStr_gplx(), actl.XtoStr_gplx(), true, EmptyStr);}
public static void Eq_date(DateAdp expd, DateAdp actl, String fmt, Object... args){Eq_wkr(expd.XtoStr_gplx(), actl.XtoStr_gplx(), true, String_.Format(fmt, args));}
public static void Eq_url(Io_url expd, Io_url actl) {Eq_wkr(expd.Raw(), actl.Raw(), true, EmptyStr);}
public static void Eq_str(String expd, byte[] actl) {Eq_wkr(expd, String_.new_u8(actl), true, EmptyStr);}
public static void Eq_bry(String expd, byte[] actl) {Eq_wkr(expd, String_.new_u8(actl), true, EmptyStr);}
public static void Eq_bry(byte[] expd, byte[] actl) {Eq_wkr(String_.new_u8(expd), String_.new_u8(actl), true, EmptyStr);}
public static void Eq_str(XtoStrAble expd, XtoStrAble actl, String msg) {Eq_wkr(expd.XtoStr(), actl.XtoStr(), true, msg);}
public static void Eq_str(XtoStrAble expd, XtoStrAble actl) {Eq_wkr(expd.XtoStr(), actl.XtoStr(), true, String_.Empty);}
public static void Eq_str_intf(XtoStrAble expd, XtoStrAble actl, String msg) {Eq_wkr(expd.XtoStr(), actl.XtoStr(), true, msg);}
public static void Eq_str_intf(XtoStrAble expd, XtoStrAble actl) {Eq_wkr(expd.XtoStr(), actl.XtoStr(), true, String_.Empty);}
public static void Eq_str_lines(String lhs, String rhs) {Eq_str_lines(lhs, rhs, EmptyStr);}
public static void Eq_str_lines(String lhs, String rhs, String note) {
if (lhs == null && rhs == null) return; // true