1   package org.daisy.pipeline.nlp.impl.matchrules;
2   
3   import java.util.regex.Matcher;
4   import java.util.regex.Pattern;
5   
6   import org.daisy.pipeline.nlp.TextCategorizer.Category;
7   import org.daisy.pipeline.nlp.TextCategorizer.MatchMode;
8   import org.daisy.pipeline.nlp.impl.MatchRule;
9   
10  /**
11   * Match text with one regex but return the text matched by another regex.
12   * Better use the Negative Lookahead syntax when it is possible.
13   */
14  public class RegexAheadMatchRule extends MatchRule {
15  
16  	private Pattern mPattern;
17  	private Pattern mPatternForward;
18  
19  	public RegexAheadMatchRule(Category category, int priority, boolean caseSensitive,
20  	        MatchMode matchMode) {
21  		super(category, priority, caseSensitive, matchMode);
22  	}
23  
24  	public void init(String regexp, String regexpForward) {
25  		int flags = Pattern.UNICODE_CASE | Pattern.MULTILINE;
26  
27  		// java7: flags |= Pattern.UNICODE_CHARACTER_CLASS;
28  
29  		if (!mCaseSensitive) {
30  			flags |= Pattern.CASE_INSENSITIVE;
31  		}
32  
33  		mPattern = Pattern.compile(regexp, flags);
34  		mPatternForward = Pattern.compile(regexpForward, flags);
35  	}
36  
37  	@Override
38  	protected String match(String input) {
39  		Matcher m = mPattern.matcher(input);
40  		switch (mMatchMode) {
41  		case FULL_MATCH:
42  			if (m.matches()) {
43  				return m.group(0);
44  			}
45  			break;
46  		case PREFIX_MATCH:
47  			if (m.lookingAt()) {
48  				Matcher m2 = mPatternForward.matcher(input);
49  				if (m2.lookingAt())
50  					return m2.group(0);
51  				else {
52  					System.err.println("** critical error **: " + mPatternForward.pattern()
53  					        + " not included in " + mPattern.pattern());
54  				}
55  			}
56  			break;
57  		}
58  
59  		return null;
60  	}
61  
62  	@Override
63  	public boolean threadsafe() {
64  		return true;
65  	}
66  }