4 * License : The MIT License
5 * Copyright(c) 2008 olyutorskii
8 package jp.sourceforge.jindolf;
10 import java.util.regex.Pattern;
11 import java.util.regex.PatternSyntaxException;
12 import jp.sourceforge.jovsonz.JsBoolean;
13 import jp.sourceforge.jovsonz.JsObject;
14 import jp.sourceforge.jovsonz.JsPair;
15 import jp.sourceforge.jovsonz.JsString;
16 import jp.sourceforge.jovsonz.JsValue;
21 public class RegexPattern{
24 public static final int IGNORECASEFLAG =
25 0x00000000 | Pattern.UNICODE_CASE | Pattern.CASE_INSENSITIVE;
26 private static final String REGEX_DELIM = "[\\s\u3000]+"; // 空白(全角含)
27 private static final String REGEX_CHAR = ".?+*\\$(|)[]{}^-&";
30 private final String editSource;
31 private final boolean isRegex;
32 private final Pattern pattern;
33 private final String comment;
39 * @param editSource リテラル文字列または正規表現
40 * @param isRegex 指定文字列が正規表現ならtrue。リテラルならfalse
43 * @throws java.util.regex.PatternSyntaxException 正規表現がおかしい
45 public RegexPattern(String editSource,
49 throws PatternSyntaxException{
51 if(editSource == null) throw new NullPointerException();
53 this.isRegex = isRegex;
54 if(comment != null) this.comment = comment;
55 else this.comment = "";
59 this.editSource = editSource;
60 regexExpr = this.editSource;
62 String newSource = "";
65 String[] tokens = editSource.split(REGEX_DELIM);
66 for(String token : tokens){
67 if(token == null || token.length() <= 0) continue;
69 if(newSource.length() <= 0) newSource = token;
70 else newSource += " " + token;
72 String quoted = "(?:" + quote(token) + ")";
73 if(regexExpr.length() <= 0) regexExpr = quoted;
74 else regexExpr += "|" + quoted;
77 this.editSource = newSource;
80 this.pattern = Pattern.compile(regexExpr, flag);
88 * @param editSource リテラル文字列または正規表現
89 * @param isRegex 指定文字列が正規表現ならtrue。リテラルならfalse
91 * @throws java.util.regex.PatternSyntaxException 正規表現がおかしい
93 public RegexPattern(String editSource,
96 throws PatternSyntaxException{
97 this(editSource, isRegex, flag, " ");
103 * 正規表現とまぎらわしい字を含むか判定する。
105 * @return 紛らわしい字を含むならtrue
107 public static boolean hasRegexChar(CharSequence seq){
108 int length = seq.length();
109 for(int pt = 0; pt < length; pt++){
110 char ch = seq.charAt(pt);
111 if(REGEX_CHAR.indexOf(ch) >= 0) return true;
117 * 任意の文字列を必要に応じて正規表現シーケンス化する。
119 * @return 引数と同じ内容の正規表現。必要がなければ引数そのまま
121 public static String quote(String text){
122 if(hasRegexChar(text)){
123 return Pattern.quote(text);
131 * @return JSON Object
133 public static JsObject encodeJson(RegexPattern regex){
134 JsObject result = new JsObject();
136 int regexFlag = regex.getRegexFlag();
137 boolean flagDotall = (regexFlag & Pattern.DOTALL) != 0;
138 boolean flagMultiline = (regexFlag & Pattern.MULTILINE) != 0;
139 boolean flagIgnoreCase = (regexFlag & IGNORECASEFLAG) != 0;
141 JsPair source = new JsPair("source", regex.getEditSource());
142 JsPair isRegex = new JsPair("isRegex", regex.isRegex());
143 JsPair dotall = new JsPair("dotall", flagDotall);
144 JsPair multiline = new JsPair("multiline", flagMultiline);
145 JsPair ignorecase = new JsPair("ignorecase", flagIgnoreCase);
146 JsPair comment = new JsPair("comment", regex.getComment());
148 result.putPair(source);
149 result.putPair(isRegex);
150 result.putPair(dotall);
151 result.putPair(multiline);
152 result.putPair(ignorecase);
153 result.putPair(comment);
160 * @param object JSON Object
163 public static RegexPattern decodeJson(JsObject object){
167 value = object.getValue("source");
168 if(value instanceof JsString){
169 source = ((JsString)value).toRawString();
175 value = object.getValue("isRegex");
176 if(value instanceof JsBoolean){
177 isRegex = ((JsBoolean)value).booleanValue();
182 int regexFlag = 0x00000000;
183 value = object.getValue("dotall");
184 if(value instanceof JsBoolean){
185 if(((JsBoolean)value).isTrue()){
186 regexFlag |= Pattern.DOTALL;
189 value = object.getValue("multiline");
190 if(value instanceof JsBoolean){
191 if(((JsBoolean)value).isTrue()){
192 regexFlag |= Pattern.MULTILINE;
195 value = object.getValue("ignorecase");
196 if(value instanceof JsBoolean){
197 if(((JsBoolean)value).isTrue()){
198 regexFlag |= IGNORECASEFLAG;
203 value = object.getValue("comment");
204 if(value instanceof JsString){
205 comment = ((JsString)value).toRawString();
210 RegexPattern result =
211 new RegexPattern(source, isRegex, regexFlag, comment);
221 public String getEditSource(){
222 return this.editSource;
229 public String getComment(){
237 public boolean isRegex(){
244 * @see java.util.regex.Pattern#flags()
246 public int getRegexFlag(){
247 return this.pattern.flags();
252 * @return コンパイルされた正規表現形式
254 public Pattern getPattern(){
260 * @return {@inheritDoc}
263 public String toString(){
264 return this.editSource;
269 * @param obj {@inheritDoc}
270 * @return {@inheritDoc}
273 public boolean equals(Object obj){
277 if( ! (obj instanceof RegexPattern) ){
280 RegexPattern other = (RegexPattern) obj;
282 String thisPattern = this.pattern.pattern();
283 String otherPattern = other.pattern.pattern();
285 if( ! thisPattern.equals(otherPattern) ) return false;
287 if(this.pattern.flags() != other.pattern.flags()) return false;
294 * @return {@inheritDoc}
297 public int hashCode(){
298 int hash = this.pattern.pattern().hashCode();
299 hash ^= this.pattern.flags();