/*
* Copyright (c) 2002-2012 Alibaba Group Holding Limited.
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.toolkit.util.regex;
import org.apache.oro.text.regex.MatchResult;
import org.apache.oro.text.regex.PatternMatcherInput;
/**
* 代表一个匹配结果, 通过这个结果, 可以做进一步的操作, 如替换, 取得匹配字符串等.
*
* @author Michael Zhou
* @version $Id: MatchItem.java,v 1.1 2003/07/03 07:26:34 baobao Exp $
*/
public class MatchItem implements MatchResult {
public static final int SUBSTITUTION_ONLY = 0;
public static final int SUBSTITUTION_WITH_PREMATCH = 1;
public static final int SUBSTITUTION_WITH_POSTMATCH = 2;
private MatchContext context;
private MatchPattern pattern;
private MatchResult result;
/**
* 创建一个匹配结果.
*
* @param context 产生这个匹配结果的context
* @param pattern 产生这个匹配结果的pattern
*/
public MatchItem(MatchContext context, MatchPattern pattern) {
this.context = context;
this.pattern = pattern;
}
/**
* 创建一个匹配结果.
*
* @param context 产生这个匹配结果的context
* @param pattern 产生这个匹配结果的pattern
* @param result 正则表达式的匹配结果
*/
public MatchItem(MatchContext context, MatchPattern pattern, MatchResult result) {
this(context, pattern);
this.result = result;
}
/**
* 取得产生这个匹配结果的context.
*
* @return 产生这个匹配结果的context
*/
public MatchContext getMatchContext() {
return this.context;
}
/**
* 取得产生这个匹配结果的pattern.
*
* @return 产生这个匹配结果的pattern
*/
public MatchPattern getMatchPattern() {
return this.pattern;
}
/**
* 取得完整的输入值字符串.
*
* @return 完整的输入值字符串
*/
public String getInput() {
return (String) this.context.getInput().getInput();
}
/**
* 实现<code>MatchResult</code>接口, 取得匹配长度.
*
* @return 匹配的长度
*/
public int length() {
return result == null ? 0 : result.length();
}
/**
* 实现<code>MatchResult</code>接口, 取得group的总数.
*
* @return group的总数, 包括group0, 也就是整个匹配
*/
public int groups() {
return result == null ? 0 : result.groups();
}
/**
* 实现<code>MatchResult</code>接口, 取得指定group的子串.
*
* @param group group号, 0代表整个匹配
* @return 指定group的子串
*/
public String group(int group) {
return result == null ? null : result.group(group);
}
/**
* 实现<code>MatchResult</code>接口, 取得指定group相对于整个匹配的位移量.
*
* @param group group号, 0代表整个匹配
* @return 指定group相对于整个匹配的位移量, 注意如果被匹配的字符串长度为0, 且位于字符串的末尾, 则位移量等于字符串的长度.
*/
public int begin(int group) {
return result == null ? -1 : result.begin(group);
}
/**
* 实现<code>MatchResult</code>接口, 取得指定group末尾相对于整个匹配的位移量.
*
* @param group group号, 0代表整个匹配
* @return 指定group末尾相对于整个匹配的位移量, 如果指定group不存在或未匹配, 则返回-1, 被匹配的字符串长度为0,
* 则返回起始位移量
*/
public int end(int group) {
return result == null ? -1 : result.end(group);
}
/**
* 实现<code>MatchResult</code>接口, 取得指定group相对于整个字符串的位移量.
*
* @param group group号, 0代表整个匹配
* @return 指定group相对于整个字符串的位移量, 如果指定group不存在或未匹配, 则返回-1
*/
public int beginOffset(int group) {
return result == null ? -1 : result.beginOffset(group);
}
/**
* 实现<code>MatchResult</code>接口, 取得指定group末尾相对于整个字符串的位移量.
*
* @param group group号, 0代表整个匹配
* @return 指定group末尾相对于整个字符串的位移量, 如果指定group不存在或未匹配, 则返回-1, 被匹配的字符串长度为0,
* 则返回起始位移量
*/
public int endOffset(int group) {
return result == null ? -1 : result.endOffset(group);
}
/**
* 实现<code>MatchResult</code>接口, 取得整个匹配的字符串, 相当于<code>group(0)</code>.
*
* @return 整个匹配的字符串
*/
@Override
public String toString() {
return result == null ? "" : result.toString();
}
/**
* 将匹配字符串前的子串, 加到指定<code>StringBuffer</code>中.
*
* @param buffer 要添加的<code>StringBuffer</code>
*/
public void appendPreMatch(StringBuffer buffer) {
PatternMatcherInput input = context.getInput();
char[] inputBuffer = input.getBuffer();
int beginOffset = input.getBeginOffset();
buffer.append(inputBuffer, beginOffset, beginOffset(0) - beginOffset);
}
/**
* 将匹配字符串后的子串, 加到指定<code>StringBuffer</code>中.
*
* @param buffer 要添加的<code>StringBuffer</code>
*/
public void appendPostMatch(StringBuffer buffer) {
PatternMatcherInput input = context.getInput();
char[] inputBuffer = input.getBuffer();
int beginOffset = endOffset(0);
buffer.append(inputBuffer, beginOffset, input.length() - beginOffset);
}
/**
* 将匹配字符串, 加到指定<code>StringBuffer</code>中.
*
* @param buffer 要添加的<code>StringBuffer</code>
*/
public void appendMatch(StringBuffer buffer) {
PatternMatcherInput input = context.getInput();
char[] inputBuffer = input.getBuffer();
int beginOffset = beginOffset(0);
buffer.append(inputBuffer, beginOffset, endOffset(0));
}
/**
* 将替换字符串加入到指定<code>StringBuffer</code>中.
*
* @param buffer 要添加的<code>StringBuffer</code>
* @param substitution 替换表达式
*/
public void appendSubstitution(StringBuffer buffer, String substitution) {
context.getSubstitution(substitution).appendSubstitution(buffer, this, 1, context.getInput(),
context.getMatcher(), pattern.getPattern());
}
/**
* 替换匹配的字符串.
*
* @param substitution 替换字符串
* @return 被替换的字符串
*/
public String substitute(String substitution) {
return substitute(substitution, SUBSTITUTION_ONLY);
}
/**
* 替换匹配的字符串.
*
* @param substitution 替换字符串
* @param options 替换选项, 可以为<code>SUBSTITUTION_ONLY</code>,
* <code>SUBSTITUTION_WITH_PREMATCH</code>或
* <code>SUBSTITUTION_WITH_POSTMATCH</code>或它们的组合
* @return 被替换的字符串
*/
public String substitute(String substitution, int options) {
StringBuffer buffer = new StringBuffer();
if ((options & SUBSTITUTION_WITH_PREMATCH) != 0) {
appendPreMatch(buffer);
}
appendSubstitution(buffer, substitution);
if ((options & SUBSTITUTION_WITH_POSTMATCH) != 0) {
appendPostMatch(buffer);
}
return buffer.toString();
}
}