How to use Matches() and Pattern correctley - java

I'm doing a assignment for school and need to build a Student class. The constructor will receive a String,"Student name". I need to verify that the given String from the user includes only letters from a-z, A-Z, and numbers 0-9.
From looking online this is what I found
boolean ans = true;
String str = ("Maor Rocky");
Pattern pattern = Pattern.compile("[A-Za-z0-9]\\w+");
Matcher matcher = pattern.matcher(str);
System.out.println(matcher.group());
if (!str.matches("[a-zA-Z0-9//s+]"))
ans = false;
System.out.println(ans);
I know it's missing something but I didn't grasp the idea of pattern and matcher yet.

thanks every one, this is the code i wrote and it works:
boolean ans = true;
if (!name.matches("^[a-zA-Z0-9 ]+$")) {
ans = false;

You need something like that:
public class Student {
private String name;
public Student(String name) throws IllegalArgumentException {
if (!name.matches("[\\w]*")) {
throw new IllegalArgumentException("name should contain only alphanumeric chars.");
}
this.name = name;
}
public String getName() {
return name;
}
}

If you have variable student of type String that will hold student name, simple check goes like this (no need to use Pattern or Matcher classes here):
String student = scanner.next();
if (student.matches("[\\w]*"))
//do something for valid username
else
//do something for invalid username
Or do it the same way every beginner would do it:
String student = scanner.next();
for (int i = 0; i < student.length(); i++) {
if (!Character.isLetterOrDigit(student.charAt(i)))
//do something for invalid username;
}

To understand the uses of Matcher you should see This link
In this example the Matcher and Pattern objects aren't doing anything because you are using a String method that works with regexp. If you wanted to use the Matcher your if would look something like this
if(matcher.matches())
ans=false;

Related

Need to check wildcard characters using regex

i am checking not allowed charters from input string
protected static Boolean validateWildcardCharacters(String inputText) {
List<String> term = Arrays.asList("!","#","#","$","%","^","&","(",")","_","+","=",";",";","{","}","[","]","'","<",">",",",".","|");
Boolean containChar = false;
for(String ch : term){
if(inputText.contains(ch)) {
containChar = true;
break;
}
};
return containChar;
But I am looking for some better solution. Maybe using Regular expression (regex).
please suggest better approach to do that.
Thanks
If you want to use a regular expression, you need to use the Pattern and Matcher classes from java.util.regex. Here is an example on how you could use it:
public static final String EXAMPLE_TEST = "Your string here : { } . / []";
public static void main(String[] args) {
Pattern pattern = Pattern.compile("[!##$%^&*(),.?\":{}|<>\\[\\]]");
Matcher matcher = pattern.matcher(EXAMPLE_TEST);
if (matcher.find())
System.out.println("found");
else {
System.out.println("not found");
}
}

Is there 'stoi()' like thing in Java?

I'm new to Java, I'm looking for a stoi()-like function in Java which is in C++.
I want like this:
If there is string like "123ABC", I want extract '123' in Integer and get the index of 'A'.
I've been looking for this, but I couldn't find it. So I upload it here.
In advance, really thank you so much who help me!
Use NumberFormat#parse(String, ParsePosition). The first argument would be "123ABC", the return value will be 123 and the ParsePosition points to A.
You can try following code:
public class Number {
public static void main(String[] args) {
String str = "A1234BCD";
extractDigit(str);
}
public static void extractDigit(String str){
str="A1234AB2C";
String numberOnly= str.replaceAll("[^0-9]", "");
System.out.println(numberOnly);
Pattern pattern = Pattern.compile("\\p{L}");
Matcher matcher = pattern.matcher(str);
if (matcher.find()) {
System.out.println(matcher.start());
}
}

how to replace multiple strings with replace method at once without making more string objects

I got a string test "{\"userName\": \"<userName>\",\"firstName\": \"<firstName>\",\"lastName\": \"<lastName>\"}". what I want is that I want to replace things in angular brackets with dynamic values. Sample code:
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
String toBeReplaced0 = "alpha";
String toBeReplaced1 = "beta";
String toBeReplaced2 = "gama";
String test = "{\"userName\": \"<userName>\",\"firstName\": \"<firstName>\",\"lastName\": \"<lastName>\"}";
}
}
Now in this code I want to replace <userName> with alpha, <firstName> with beta, <lastName> with gama at once without making multiple string objects. This is not a homework question. test string can have more angular elements in it to be filled with dynamic values. How can I do this with replace method or any thing else..
Matcher.appendReplacement could be an option. Example:
public static void main(String[] args){
String toBeReplaced0 = "alpha";
String toBeReplaced1 = "beta";
String toBeReplaced2 = "gama";
String test = "{\"userName\": \"<userName>\",\"firstName\": \"<firstName>\",\"lastName\": \"<lastName>\"}";
System.out.println(findAndReplace(test,toBeReplaced0,toBeReplaced1,toBeReplaced2));
}
public static String findAndReplace(String original, String... replacments){
Pattern p = Pattern.compile("<[^<]*>");
Matcher m1 = p.matcher(original);
// count the matches
int count = 0;
while (m1.find()){
count++;
}
// if matches count equals replacement params length replace in the given order
if(count == replacments.length){
Matcher m = p.matcher(original);
StringBuffer sb = new StringBuffer();
int i = 0;
while (m.find()) {
m.appendReplacement(sb, replacments[i]);
i++;
}
m.appendTail(sb);
return sb.toString();
}
//else return original
return original;
}
If that's JSON, I'd prefer to use a JSON library to dynamically construct the resultant string and mitigate any possible syntactic errors.
If you really want to use String.replaceAll() or similar, I wouldn't expect that to be a problem in the above limited scope. Simply chain together your calls (e.g. see this tutorial)
Note that strings are immutable, and as such you can't easily do this without creating new string objects. If that's really a concern, perhaps you need to modify an array of chars (but that will be a non-trivial task when substituting multiple strings of varying lengths differing from their placeholders).
Simply:
String result = orig.replace("<userName>", "replacement");
(not forgetting that strings are immutable and so you have to use the result returned from this call)
I would do that with the StringTemplate library. With your example works out of the box:
<dependency>
<groupId>org.antlr</groupId>
<artifactId>ST4</artifactId>
<version>4.0.8</version>
<scope>compile</scope>
</dependency>
// Given
final ST template = new ST("{\"userName\": \"<userName>\",\"firstName\": \"<firstName>\",\"lastName\": \"<lastName>\"}");
template.add("userName", "alpha");
template.add("firstName", "beta");
template.add("lastName", "gamma");
// When
final String result = template.render();
// Then
Assert.assertEquals("{\"userName\": \"alpha\",\"firstName\": \"beta\",\"lastName\": \"gamma\"}", result);

Using regular expressions in Java to do a partial search

ETA at 9:42 p.m. March 21: Dumb mistake. I made sure the original creation of the object made the name .toUpperCase(). The partial search didn't find the search term because they weren't capitalized. Edited code below. Thank you all for the help.
I'm trying to figure out how to use regular expressions to find out if any pattern of characters matches what's in the object.
For instance, if the name associated with the object was "StackOverflow," I'd like for someone to search "ck" and make the if statement true. So, why is my if statement here not returning true?
ETA: i.getName() returns a string. The program is looping through an ArrayList of objects to find which object has a name that matches the input.
System.out.println("What name or partial name would you like to filter?");
String name = input.nextLine();
int count = 0;
for (MyObject i: testObject) {
if (i.getName().matches(".*" + name.toUpperCase() + ".*")) {
count++;
}
}
You need to use toString(). You can not apply matches over an object.
Try that:
System.out.println("What name or partial name would you like to filter?");
String name = input.nextLine();
int count = 0;
for (Object i: testObject) {
if (i.getName().toString().matches(".*" + name + ".*")) {
count++;
}
}
I'm not sure why your code doesn't work, but see this working example, perhaps you have a small mistake somewhere.
Here's a MyObject class that has a name field:
class MyObject {
private final String name;
public MyObject(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
and here's the program that find matches:
List<MyObject> myObjects = new ArrayList<MyObject>();
myObjects.add(new MyObject("Stack Overflow"));
myObjects.add(new MyObject("Stack Exchange"));
Scanner input = new Scanner(System.in);
System.out.print("What name or partial name would you like to filter? ");
String pattern = input.nextLine();
int count = 0;
for (MyObject i: myObjects) {
if (i.getName().matches(".*" + pattern + ".*")) {
count++;
}
}
System.out.println("Matches: " + count);
Input:
ck
Output:
Matches: 2

How to iterate over regexp compliant strings

What is the easiest way to implement a class (in Java) that would serve as an iterator over the set of all values which conform to a given regexp?
Let's say I have a class like this:
public class RegexpIterator
{
private String regexp;
public RegexpIterator(String regexp) {
this.regexp = regexp;
}
public abstract boolean hasNext() {
...
}
public abstract String next() {
...
}
}
How do I implement it? The class assumes some linear ordering on the set of all conforming values and the next() method should return the i-th value when called for the i-th time.
Ideally the solution should support full regexp syntax (as supported by the Java SDK).
To avoid confusion, please note that the class is not supposed to iterate over matches of the given regexp over a given string. Rather it should (eventually) enumerate all string values that conform to the regexp (i.e. would be accepted by the matches() method of a matcher), without any other input string given as argument.
To further clarify the question, let's show a simple example.
RegexpIterator it = new RegexpIterator("ab?cd?e");
while (it.hasNext()) {
System.out.println(it.next());
}
This code snippet should have the following output (the order of lines is not relevant, even though a solution which would list shorter strings first would be preferred).
ace
abce
ecde
abcde
Note that with some regexps, such as ab[A-Z]*cd, the set of values over which the class is to iterate is ininite. The preceeding code snippet would run forever in these cases.
Do you need to implement a class? This pattern works well:
Pattern p = Pattern.compile("[0-9]+");
Matcher m = p.matcher("123, sdfr 123kjkh 543lkj ioj345ljoij123oij");
while (m.find()) {
System.out.println(m.group());
}
output:
123
123
543
345
123
for a more generalized solution:
public static List<String> getMatches(String input, String regex) {
List<String> retval = new ArrayList<String>();
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(input);
while (m.find()) {
retval.add(m.group());
}
return retval;
}
which then can be used like this:
public static void main(String[] args) {
List<String> matches = getMatches("this matches _all words that _start _with an _underscore", "_[a-z]*");
for (String s : matches) { // List implements the 'iterable' interface
System.out.println(s);
}
}
which produces this:
_all
_start
_with
_underscore
more information about the Matcher class can be found here: http://docs.oracle.com/javase/6/docs/api/java/util/regex/Matcher.html
Here is another working example. It might be helpful :
public class RegxIterator<E> implements RegexpIterator {
private Iterator<E> itr = null;
public RegxIterator(Iterator<E> itr, String regex) {
ArrayList<E> list = new ArrayList<E>();
while (itr.hasNext()) {
E e = itr.next();
if (Pattern.matches(regex, e.toString()))
list.add(e);
}
this.itr = list.iterator();
}
#Override
public boolean hasNext() {
return this.itr.hasNext();
}
#Override
public String next() {
return this.itr.next().toString();
}
}
If you want to use it for other dataTypes(Integer,Float etc. or other classes where toString() is meaningful), declare next() to return Object instead of String. Then you may able be to perform a typeCast on the return value to get back the actual type.

Categories

Resources