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