This commit is contained in:
Looly 2023-03-26 12:50:34 +08:00
parent f970dc7632
commit 376cfe4271
4 changed files with 95 additions and 7 deletions

View File

@ -2552,7 +2552,8 @@ public class CharSequenceUtil extends StrChecker {
}
/**
* 去掉字符包装如果未被包装则返回原字符串
* 去掉字符包装如果未被包装则返回原字符串<br>
* 此方法要求prefix和suffix都存在如果只有一个不做去除
*
* @param str 字符串
* @param prefix 前置字符串

View File

@ -4,7 +4,22 @@ import java.io.Serializable;
import java.util.function.BiPredicate;
/**
* 字符串区域匹配器用于匹配字串是头部匹配还是尾部匹配
* 字符串区域匹配器用于匹配字串是头部匹配还是尾部匹配<br>
* offset用于锚定开始或结束位置正数表示从开始偏移负数表示从后偏移
* <pre>
* a b c d e f
* | | | |
* 0 1 c d -2 -1
* </pre>
* <p>
* 例如以下匹配都为{@code true}
* <pre>
* offset str strToCheck
* 0 abcdef ab
* 1 abcdef bc
* -1 abcdef ef
* -2 abcdef de
* </pre>
*
* @author looly
* @since 6.0.0
@ -14,7 +29,10 @@ public class StrRegionMatcher implements BiPredicate<CharSequence, CharSequence>
private final boolean ignoreCase;
private final boolean ignoreEquals;
private final boolean isPrefix;
/**
* 匹配位置正数表示从开始偏移负数表示从后偏移
*/
private final int offset;
/**
* 构造
@ -24,9 +42,20 @@ public class StrRegionMatcher implements BiPredicate<CharSequence, CharSequence>
* @param isPrefix {@code true}表示检查开头匹配{@code false}检查末尾匹配
*/
public StrRegionMatcher(final boolean ignoreCase, final boolean ignoreEquals, final boolean isPrefix) {
this(ignoreCase, ignoreEquals, isPrefix ? 0 : -1);
}
/**
* 构造
*
* @param ignoreCase 是否忽略大小写
* @param ignoreEquals 是否忽略字符串相等的情况
* @param offset 匹配位置正数表示从开始偏移负数表示从后偏移
*/
public StrRegionMatcher(final boolean ignoreCase, final boolean ignoreEquals, final int offset) {
this.ignoreCase = ignoreCase;
this.ignoreEquals = ignoreEquals;
this.isPrefix = isPrefix;
this.offset = offset;
}
@Override
@ -38,9 +67,11 @@ public class StrRegionMatcher implements BiPredicate<CharSequence, CharSequence>
return null == str && null == strToCheck;
}
final int toffset = isPrefix ? 0 : str.length() - strToCheck.length();
final int strToCheckLength = strToCheck.length();
final int toffset = this.offset >= 0 ?
this.offset : str.length() - strToCheckLength + this.offset + 1;
final boolean matches = str.toString()
.regionMatches(ignoreCase, toffset, strToCheck.toString(), 0, strToCheck.length());
.regionMatches(ignoreCase, toffset, strToCheck.toString(), 0, strToCheckLength);
if (matches) {
return (false == ignoreEquals) || (false == StrUtil.equals(str, strToCheck, ignoreCase));

View File

@ -7,7 +7,7 @@ import java.util.function.Predicate;
import java.util.function.UnaryOperator;
/**
* 字符串头尾去除器<br>
* 字符串头尾指定字符去除器<br>
* 按照断言除去字符串头尾部的断言为真的字符如果字符串是{@code null}依然返回{@code null}
*
* @author looly

View File

@ -0,0 +1,56 @@
package cn.hutool.core.text;
import org.junit.Assert;
import org.junit.Test;
public class StrRegionMatcherTest {
@Test
public void matchPrefixTest() {
final StrRegionMatcher matcher = new StrRegionMatcher(
false, false, true);
final boolean test = matcher.test("abcdef", "ab");
Assert.assertTrue(test);
}
@Test
public void matchSuffixTest() {
final StrRegionMatcher matcher = new StrRegionMatcher(
false, false, false);
final boolean test = matcher.test("abcdef", "ef");
Assert.assertTrue(test);
}
@Test
public void matchOffsetTest1() {
final StrRegionMatcher matcher = new StrRegionMatcher(
false, false, 1);
final boolean test = matcher.test("abcdef", "bc");
Assert.assertTrue(test);
}
@Test
public void matchOffsetTest2() {
final StrRegionMatcher matcher = new StrRegionMatcher(
false, false, -2);
final boolean test = matcher.test("abcdef", "de");
Assert.assertTrue(test);
}
@Test
public void matchOffsetTest3() {
// 部分越界
final StrRegionMatcher matcher = new StrRegionMatcher(
false, false, 5);
final boolean test = matcher.test("abcdef", "de");
Assert.assertFalse(test);
}
@Test
public void matchOffsetTest4() {
// 完全越界
final StrRegionMatcher matcher = new StrRegionMatcher(
false, false, 6);
final boolean test = matcher.test("abcdef", "de");
Assert.assertFalse(test);
}
}