使用通配符匹配您的字符串






3.67/5 (2投票s)
本文为您提供了如何使用 * 和 ?(所谓的通配符)比较字符串的思路。
引言
你是否曾经在Windows操作系统中搜索过文件和文件夹?通常,大多数用户会尝试搜索各种*.doc文件、*.pdf文件等。我们通常通过在Windows操作系统的搜索窗口的文本框中输入*.doc或*.pdf来进行搜索。当然,Windows操作系统还提供了一些其他的更具体的搜索实用程序。然而,这种搜索方式被应用于许多应用程序中。如果一个应用程序提供了这种功能,它就会被认为是该应用程序的最佳特性。
背景
对于一个应用程序来说,用户将如何提供搜索条件,这一点至关重要。并非所有类型的搜索条件都总是可行的。通常,人们普遍认为,用户可以基于某些规范进行搜索。就此规范而言,我们通常通过提供通配符来进行搜索。通配符是*
和?
。这些字符背后有一个概念。我希望你了解它。这种搜索规范在各种应用程序中反复出现。如果你正在开发一个应用程序,那么将有一个文本字段,用户必须通过提供*
或?
或两者与字母数字字符的组合来搜索人员的姓名。例如,如果我需要搜索一个名字,我可以输入J*,这样我的输出可能是“John”、“Johnson”或以“J”开头的任何内容。还有一种情况是我需要精确地搜索四个字符,所以我可以将我的搜索条件设置为????。但是,用户可以给出任何类型的组合来搜索String
模式。在基于Java的应用程序中,你可以使用正则表达式来实现此功能。但是正则表达式的形成取决于你。有时我们可能会发现很难形成精确的正则表达式以满足预期。但是,如果要求仅仅是基于通配符模式查找String
匹配项,我已经在下面提供了一个示例。你可以在任何你希望基于通配符模式搜索名称的地方使用它。
Using the Code
以下类是一个实用程序类,你可以将其用作通配符模式的string
查找器。例如,你的原始String
是“John
”,你想查找原始string
是否与通配符模式“J*
”匹配。你可以轻松做到。我已经提供了测试工具类来测试功能。你可以通过各种方式进行测试。
package com.ddlabs.core.util;
import java.util.Vector;
/**This class is a utility for finding
* the String based upon the wild card
* pattern. For example if the actual
* String "John" and your wild card pattern
* is "J*", it will return true.
* @author Debadatta Mishra(PIKU)
*
*/
public class WildCardStringFinder
{
/**
* String variable for wild card pattern
*/
private String wildCardPatternString;
/**
* Variable for the length of the wild card pattern
*/
private int wildCardPatternLength;
/**
* Boolean variable to for checking wild cards,
* It is false by default.
*/
private boolean ignoreWildCards;
/**
* Boolean variable to know whether the pattern
* has leading * or not.
*/
private boolean hasLeadingStar;
/**
* Boolean variable to know whether the pattern
* has * at the end.
*/
private boolean hasTrailingStar;
/**
* A String array to contain chars
*/
private String charSegments[];
/**
* Variable to maintain the boundary of the String.
*/
private int charBound;
/**
* Default constructor
*/
public WildCardStringFinder()
{
super();
ignoreWildCards = false;
}
/**This is the public method which will be called to match a String
* with the wild card pattern.
* @param actualString of type String indicating the String to be matched
* @param wildCardString of type String indicating the wild card String
* @return true if matches
*/
public boolean isStringMatching( String actualString , String wildCardString )
{
wildCardPatternString = wildCardString;
wildCardPatternLength = wildCardString.length();
setWildCards();
return doesMatch( actualString, 0, actualString.length() );
}
/**
* This method is used to set the wild cards.
* The pattern for the wild card may be *, ? or
* a combination of *,? and alphanumeric character.
*/
private void setWildCards()
{
if(wildCardPatternString.startsWith("*"))
{
hasLeadingStar = true;
}
if (wildCardPatternString.endsWith("*") && wildCardPatternLength > 1 )
{
hasTrailingStar = true;
}
Vector temp = new Vector();
int pos = 0;
StringBuffer buf = new StringBuffer();
while(pos < wildCardPatternLength)
{
char c = wildCardPatternString.charAt(pos++);
switch(c)
{
case 42: // It refers to *
if(buf.length() > 0)
{
temp.addElement(buf.toString());
charBound += buf.length();
buf.setLength(0);
}
break;
case 63: // It refers to ?
buf.append('\0');
break;
default:
buf.append(c);
break;
}
}
if(buf.length() > 0)
{
temp.addElement(buf.toString());
charBound += buf.length();
}
charSegments = new String[temp.size()];
temp.copyInto(charSegments);
}
/**This is the actual method which makes comparison
* with the wild card pattern.
* @param text of type String indicating the actual String
* @param startPoint of type int indicating the start index
* of the String
* @param endPoint of type int indicating the end index of
* the String
* @return true if matches.
*/
private final boolean doesMatch(String text, int startPoint, int endPoint)
{
int textLength = text.length();
if(startPoint > endPoint)
{
return false;
}
if(ignoreWildCards)
{
return endPoint - startPoint == wildCardPatternLength
&& wildCardPatternString.regionMatches(false, 0, text,
startPoint, wildCardPatternLength);
}
int charCount = charSegments.length;
if(charCount == 0 && ( hasLeadingStar || hasTrailingStar ) )
{
return true;
}
if(startPoint == endPoint)
{
return wildCardPatternLength == 0;
}
if(wildCardPatternLength == 0)
{
return startPoint == endPoint;
}
if(startPoint < 0)
{
startPoint = 0;
}
if(endPoint > textLength)
{
endPoint = textLength;
}
int currPosition = startPoint;
int bound = endPoint - charBound;
if(bound < 0)
{
return false;
}
int i = 0;
String currString = charSegments[i];
int currStringLength = currString.length();
if( !hasLeadingStar )
{
if(!isExpressionMatching(text, startPoint,
currString, 0, currStringLength))
{
return false;
}
i++;
currPosition += currStringLength;
}
if(charSegments.length == 1 && !hasLeadingStar && !hasTrailingStar)
{
return currPosition == endPoint;
}
for(; i < charCount; i++)
{
currString = charSegments[i];
int k = currString.indexOf('\0');
int currentMatch;
currentMatch = getTextPosition(text, currPosition,
endPoint, currString);
if(k < 0)
{
if(currentMatch < 0)
{
return false;
}
}
currPosition = currentMatch + currString.length();
}
if(!hasTrailingStar && currPosition != endPoint)
{
int clen = currString.length();
return isExpressionMatching(text,
endPoint - clen, currString, 0, clen);
}
return i == charCount;
}
/**This method finds the position of the String based upon the
* wild card pattern. It also considers some special case
* like *.* and ???.? and their combination.
* @param textString of type String indicating the String
* @param start of type int indicating the start index of the String
* @param end of type int indicating the end index of the String
* @param posString of type indicating the position after wild card
* @return the position of the String
*/
private final int getTextPosition(String textString, int start,
int end, String posString)
{
/*
* String after *
*/
int plen = posString.length();
int max = end - plen;
int position = -1;
int i = textString.indexOf(posString, start);
/*
* The following conditions are met for the
* special case where user give *.*
*/
if( posString.equals("."))
{
position = 1;
}
if(i == -1 || i > max)
{
position = -1;
}
else
{
position = i;
}
return position;
}
/**This method is used to match the wild card with the String
* based upon the start and end index.
* @param textString of type String indicating the String
* @param stringStartIndex of type int indicating the start
* index of the String.
* @param patternString of type String indicating the pattern
* @param patternStartIndex of type int indicating the start index
* @param length of type int indicating the length of pattern
* @return true if matches otherwise false
*/
private boolean isExpressionMatching(String textString, int stringStartIndex,
String patternString, int patternStartIndex, int length)
{
while(length-- > 0)
{
char textChar = textString.charAt(stringStartIndex++);
char patternChar = patternString.charAt(patternStartIndex++);
if ((ignoreWildCards || patternChar != 0)
&& patternChar != textChar
&& (textChar != patternChar
&& textChar != patternChar))
{
return false;
}
}
return true;
}
}
以下类是上述类的测试工具类。
package com.ddlabs.core.util;
/**This is a test harness class to test
* the wild card pattern on a particular
* String.
* @author Debadatta Mishra(PIKU)
*
*/
public class WildCardTestharness
{
public static void main(String[] args)
{
String name = "John";
String searchString = "John";
WildCardStringFinder finder = new WildCardStringFinder();
boolean flag = finder.isStringMatching(name, searchString);
System.out.println(flag);
}
}
关注点
要测试上述程序,请创建程序中提到的适当包。你也可以创建自己的包,并修改上述程序中的包名。你可以在你最喜欢的Java编辑器中拥有所有代码。我希望你会喜欢我的文章。如果你发现任何问题或错误,请随时通过电子邮件向我发送邮件,邮箱地址为debadattamishra@aol.com。本文仅适用于那些刚开始接触Java开发的人。本文不具有任何商业意义。请向我提供有关本文的反馈。
历史
- 2008年7月23日:初始发布