Introduction
Have you ever searched for files and folders in Windows operating system? Generally most of the users try to search various *.doc files, *.pdf files, etc. We generally search by giving *.doc or *.pdf in the text box of the search window of the Windows OS. Of course, Windows OS provides some other more specific search utilities. However this kind of search is used in many applications. If an application provides this kind of facility, it is considered as the best feature of that application.
Background
It is always important for an application as to how the user is going to provide a search condition. All kinds of search conditions are not always feasible. Generally it has been universally endorsed that a user can search based upon certain specifications. As far this specification is concerned, we generally search by providing wild card characters. The wild card characters are *
and ?
. There is a concept behind these characters. I hope you know about it. This kind of search specification is recurrent in various applications. If you are working on an application, there will be a text field where a user has to search the name of the persons by giving *
or ?
or a combination of both and alphanumeric characters. For example, if I have to search a name, I can give J* so that my out may be “John”, “Johnson” or anything that starts with “J”. There is another case where I have to search exactly for four characters, so I can give my search condition as ???? . However, the user can give any kind of combination to search the String
pattern. In case of Java based applications, you can achieve this feature by using regular expression. But the formation of regular expression depends upon you. Sometimes we may find it difficult to form the exact regular expression to meet the expectation. However if the requirement is only to find out the match is a String
based upon the wild card pattern, I have provided an example below. You can use it anywhere that you want to search a name based upon the wild card pattern.
Using the Code
The following class is a utility class that you can use as string
finder for wild card pattern. For example, you have your original String
as “John
” and you want to find whether the original string
matches with the wild pattern as “J*
”. You can do it easily. I have provided the test harness class to test the functionality. You can test in various ways.
package com.ddlabs.core.util;
import java.util.Vector;
public class WildCardStringFinder
{
private String wildCardPatternString;
private int wildCardPatternLength;
private boolean ignoreWildCards;
private boolean hasLeadingStar;
private boolean hasTrailingStar;
private String charSegments[];
private int charBound;
public WildCardStringFinder()
{
super();
ignoreWildCards = false;
}
public boolean isStringMatching( String actualString , String wildCardString )
{
wildCardPatternString = wildCardString;
wildCardPatternLength = wildCardString.length();
setWildCards();
return doesMatch( actualString, 0, actualString.length() );
}
private void setWildCards()
{
if(wildCardPatternString.startsWith("*"))
{
hasLeadingStar = true;
}
if (wildCardPatternString.endsWith("*") && wildCardPatternLength > 1 )
{
hasTrailingStar = true;
}
Vector<string /> temp = new Vector<string />();
int pos = 0;
StringBuffer buf = new StringBuffer();
while(pos < wildCardPatternLength)
{
char c = wildCardPatternString.charAt(pos++);
switch(c)
{
case 42:
if(buf.length() > 0)
{
temp.addElement(buf.toString());
charBound += buf.length();
buf.setLength(0);
}
break;
case 63:
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);
}
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;
}
private final int getTextPosition(String textString, int start,
int end, String posString)
{
int plen = posString.length();
int max = end - plen;
int position = -1;
int i = textString.indexOf(posString, start);
if( posString.equals("."))
{
position = 1;
}
if(i == -1 || i > max)
{
position = -1;
}
else
{
position = i;
}
return position;
}
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;
}
}
The following class is a test harness class for the above class.
package com.ddlabs.core.util;
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);
}
}
Points of Interest
To test the above programs, please create the appropriate package as mentioned in the program. You can also create your own package and modify the package name in the above programs. You can have all the code in your favorite Java editor. I hope that you will enjoy my article. If you find any problems or errors, please feel free to send me an email at debadattamishra@aol.com. This article is only meant for those who are new to Java development. This article does not bear any commercial significance. Please provide me the feedback about this article.
History
- 23rd July, 2008: Initial post