I'm trying to check a String for a particular format in Java. The format must be LetterLetterNumberNumber
Example: js34
If this format is not not entered then my program will throw a format exception. For some reason I'm having a hard time wrapping my head around this.
I considered using String.matches() method but I don't think it would work here.
import java.util.Scanner;
class Main {
public static void main(String[] args) {
String user;
System.out.print("Enter your String: ");
user = (new Scanner(System.in)).nextLine();//format must match LetterLetterNumberNumber
//format checker goes here
}
}
class formatException extends Exception{
public formatException(){
System.out.print(toString());
}
public String toString(){
return "Incorrect format!";
}
}
Like the comment suggested, you can use String.matches() with regex. It'll look something like this:
//format checker goes here
if (!user.matches("^[A-Za-z]{2}\\d{2}$")) {
throw new FormatException();
}
I'll explain the regex. The "^" signifies that we want to match the start of the string. Then "[A-Za-z]" matches any upper- or lowercase letter. "{2}" means we want to match that two times. "\d" matches a digit. (The double backslash means we want an actual backslash and not an escape character like "\n" (newline).) Then the "{2}" again, because we want two digits. And finally "$" matches the end of the string.
Note: I made formatException start with uppercase.
Related
Write a procedure loadDocument(String name) which will load and analyze lines after lines searching for link in every line. The link format is as follows: 5 characters link= (it can be mixed capital and small letters) after which there is a correct identifier. The correct identifier starts from letter (small or capital) follows by zero or more occurrences of letters or digits or underline _. The procedure has to print subsequent identifiers, each one in a separated line. Before printing, the identifiers have to be changed to small letters. The document ends with line with the text eod, which means end of document.
My code:
public static void loadDocument(String name, Scanner scan) {
while(scan.hasNext()) {
String line = scan.nextLine();
if(line.equals("eod")) {
return;
}
else if(line.matches("link="+name) && correctLink(name)) {
String identifier = name.toLowerCase();
System.out.println(identifier);
}
else
continue;
}
}
// accepted only small letters, capital letter, digits and '_' (but not on the begin)
public static boolean correctLink(String link) {
if(link.matches("^[a-zA-Z]+[0]+||[0-9]+||_"))
return true;
else
return false;
}
How to write if line equal to link=, return whatever's after link=?
My problem is in this code:
else if(line.matches("link="+name) && correctLink(name)) {
String identifier = name.toLowerCase();
System.out.println(identifier);
}
For example, if the input is link=abc, I want it to print abc.
First I would suggest that you get used to compare to literal strings "the other way round" - this will save you from a lot NullPointerExceptions (but this is just a side comment):
if ("eod".equals(line))
You can use #Ofer s example (it is generated from https://regex101.com, a nice page to play around with regular expressions and get them explained btw.) but you should use a different regex:
final String regex = "link=([a-z][a-z0-9_]*)";
and a different option for the pattern:
final Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
I used the CASE_INSENSITIVE option to make the "link" also trigger for mixed case writings (like "Link", "liNk" and so on). Therefore I also could skip the uppercase letters from the actual regex, as [a-z] will also match uppercase letters with that option, and that's what was requested.
The "magic" here is that you put the expression that you later want to "read" from the pattern matcher into parenthesis "()" - this marks a "group". Group 0 always gives back the full match (including the "link=" here).
You can play around with that expression at https://regex101.com/r/id2CP2/1
Please don't forget to convert the identifiers (you get them from matcher.group(i)) to lowercase before you output them.
I'd like to know how to detect word that is between any characters except a letter from alphabet. I need this, because I'm working on a custom import organizer for Java. This is what I have already tried:
The regex expression:
[^(a-zA-Z)]InitializationEvent[^(a-zA-Z)]
I'm searching for the word "InitializationEvent".
The code snippet I've been testing on:
public void load(InitializationEvent event) {
It looks like adding space before the word helps... is the parenthesis inside of alphabet range?
I tested this in my program and it didn't work. Also I checked it on regexr.com, showing same results - class name not recognized.
Am I doing something wrong? I'm new to regex, so it might be a really basic mistake, or not. Let me know!
Lose the parentheses:
[^a-zA-Z]InitializationEvent[^a-zA-Z]
Inside [], parentheses are taken literally, and by inverting the group (^) you prevent it from matching because a ( is preceding InitializationEvent in your string.
Note, however, that the above regex will only match if InitializationEvent is neither at the beginning nor at the end of the tested string. To allow that, you can use:
(^|[^a-zA-Z])InitializationEvent([^a-zA-Z]|$)
Or, without creating any matching groups (which is supposed to be cleaner, and perform better):
(?:^|[^a-zA-Z])InitializationEvent(?:[^a-zA-Z]|$)
how to detect word that is between any characters except a letter from alphabet
This is the case where lookarounds come handy. You can use:
(?<![a-zA-Z])InitializationEvent(?![a-zA-Z])
(?<![a-zA-Z]) is negative lookbehind to assert that there is no alphabet at previous position
(?![a-zA-Z]) is negative lookahead to assert that there is no alphabet at next position
RegEx Demo
The parentheses are causing the problem, just skip them:
"[^a-zA-Z]InitializationEvent[^a-zA-Z]"
or use the predefined non-word character class which is slightly different because it also excludes numbers and the underscore:
"\\WInitializationEvent\\W"
But as it seems you want to match a class name, this might be ok because the remaining character are exactly those that are allowed in a class name.
I'm not sure about your application but from a regexp perspective you can use negative lookaheads and negative lookbehinds to define what cannot surround the String to specify a match.
I have added the negative lookahead (?![a-zA-Z]) and the negative lookbehind (?<![a-zA-Z]) in place of your [^(a-zA-Z)] originally supplied to create: (?<![a-zA-Z])InitializationEvent(?![a-zA-Z])
Quick Fiddle I created:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class HelloWorld{
public static void main(String []args){
String pattern = "(?<![a-zA-Z])InitializationEvent(?![a-zA-Z])";
String sourceString = "public void load(InitializationEvent event) {";
String sourceString2 = "public void load(BInitializationEventA event) {";
Pattern r = Pattern.compile(pattern);
Matcher m = r.matcher(sourceString);
if (m.find( )) {
System.out.println("Found value of pattern in sourceString: " + m.group(0) );
} else {
System.out.println("NO MATCH in sourceString");
}
Matcher m2 = r.matcher(sourceString2);
if (m2.find( )) {
System.out.println("Found value of pattern in sourceString2: " + m2.group(0) );
} else {
System.out.println("NO MATCH in sourceString2");
}
}
}
output:
sh-4.3$ java -Xmx128M -Xms16M HelloWorld
Found value of pattern in sourceString: InitializationEvent
NO MATCH in sourceString2
You seem really close:
[^(a-zA-Z)]*(InitializationEvent)[^(a-zA-Z)]*
I think this is what you are looking for. The asterisk provides a match for zero or many of the character or group before it.
EDIT/UPDATE
My apologies on the initial response.
[^a-zA-Z]+(InitializationEvent)[^a-zA-Z]+
My regex is a little rusty, but this will match on any non-alphabet character one or many times prior to the InitializationEvent and after.
I want to remove a numeric value from a specific position position. I have used a regex but it deletes every numeric value from the String.
I have these Strings:
Draft1(admin)
Draft2(adminn)
Draft21(admin23)
Draft112(admin211)
And I want these strings as:
Draft(admin)
Draft(adminn)
Draft(admin23)
Draft(admin211)
currently I've used regex:
name = name.replaceAll("\\d", "");
which replaces all the numeric values and I get something like:
Draft(admin)
You can simply use String#replaceFirst with regex like (?i)(?<=Draft)\d+ to delete this digits:
name = name.replaceFirst("(?i)(?<=Draft)\\d+","");
Where:
(?i) makes regex caseinsensitive, so the Draft could be even DRAFT or draft
(?<=Draft) is lookbehind for Draft word, which asserts that what immediately precedes the current position in the string is Draft
\\d+ are one or more digit to be replaced
(?<=Draft)\\d+\\b
You can use this and replace by empty string.The lookbehind will make sure it replace only numbers after Draft.
You could try this
class String111
{
public static void main(String args[])
{
String s1="Draft1(admin)";
String s2="Draft21(admin23)";
System.out.println(s1.substring(0,s1.indexOf('(')).replaceAll("\\d", "")+s1.substring(s1.indexOf('('),s1.length()));
System.out.println(s2.substring(0,s2.indexOf('(')).replaceAll("\\d", "")+s2.substring(s2.indexOf('('),s2.length()));
}
}
This works
public static void main(String[] args) {
String name = "Draft112(admin211)";
name = name.replaceAll("\\d+(?=\\()","");
System.out.println(name);
}
Hey I am writing a calculator script in Java.
I am currently stuck trying to find out a way to find if any of the characters in a sting are in an ArrayList.
For example:
I have to have the input as a String I pass this string into a method of which has access to an array list with the operators and operands in it. How can I make sure that the string only contains the operands and operators within this array list?
Thanks, Ciaran
Here is the code that I have so far with the input being passed in..
import java.util.*;
public class stringCalculator {
private String[] operators = {"+","-","/","*"};
public stringCalculator(String userinput){
System.out.println(userinput);
public boolean checkInput(){
}
}
}
Here is the new code.
import java.util.*;
public class stringCalculator {
private String userinput;
HashSet<String> op = new HashSet<String>();
public stringCalculator(String userinput){
this.userinput = userinput;
//System.out.println(userinput);
HashSet<String> op = new HashSet<String>();
op.add("+");
op.add("-");
op.add("*");
op.add("/");
this.op = op;
System.out.println(op);
}
public void checkTheInput(){
System.out.println(userinput);
}
public boolean checkInput(){
return op.contains(userinput);
}
}
Edited to meet requirement as per comments
To return true if a string contains only -+/* or digits:
public boolean checkInput(String input) {
return input.matches("[-+/*0-9]+");
}
This uses a regular expression to assert that the string contains only the specified characters. A breakdown of the regex:
[...] is a character class, which lists the characters allowed
+ means "one or more of the preceding expression" (in this case the character class)
Note that the minus sign in a character class is for a range of characters, eg 0-9 means 0123456789. However, when a minus is used either first of last in a character class, it means a literal minus (not a range).
Another note about String.matches() - it must match the whole string to return true. This is different from many other languages, where the similar method/function would return true if part of the string matches.
So, you want to take out the numbers, and then check if the remaining characters are all contained in opereators. Assuming your input String is not too long, I'd suggest you use a HashSet instead of String[] for operators. This way, you can use the [contains(Object)][1] method (which will be O(1) instead of O(n)) for anything that's not a number in your String.
As validation goes, however, you'll still have to check for much more, such as: "4++5/-3", where the operands are valid, but the overall expression isn't.
If you want to calculate expressions such as:
(3+4)*5
(which is in INFIX format). it is not very wise to read the string straightly. you should first convert the input to POSTFIX or Reverse Polish format like:
34+5*
This can be done reading characters one by one and using a stack. In that case you can check the characters on the fly one by one storing operators in a Set or Map.
I would recommend having a look at http://en.wikipedia.org/wiki/Reverse_Polish_notation for POSTFIX format and http://www.softwareandfinance.com/Java/Infix_Postfix_Converter.html
for example conversion code.
g.:
String string="Marc Louie, Garduque Bautista";
I want to check if a string contains only words, a comma and spaces. i have tried to use regex and the closest I got is this :
String pattern = "[a-zA-Z]+(\\s[a-zA-Z]+)+";
but it doesnt check if there is a comma in there or not. Any suggestion ?
You need to use the pattern
^[A-Za-z, ]++$
For example
public static void main(String[] args) throws IOException {
final String input = "Marc Louie, Garduque Bautista";
final Pattern pattern = Pattern.compile("^[A-Za-z, ]++$");
if (!pattern.matcher(input).matches()) {
throw new IllegalArgumentException("Invalid String");
}
}
EDIT
As per Michael's astute comment the OP might mean a single comma, in which case
^[A-Za-z ]++,[A-Za-z ]++$
Ought to work.
Why not just simply:
"[a-zA-Z\\s,]+"
Use this will best
"(?i)[a-z,\\s]+"
If you mean "some words, any spaces and one single comma, wherever it occurs to be" then my feeling is to suggest this approach:
"^[^,]* *, *[^,]*$"
This means "Start with zero or more characters which are NOT (^) a comma, then you could find zero or more spaces, then a comma, then again zero or more spaces, then finally again zero or more characters which are NOT (^) a comma".
To validate String in java where No special char at beginning and end but may have some special char in between.
String strRGEX = "^[a-zA-Z0-9]+([a-zA-Z0-9-/?:.,\'+_\\s])+([a-zA-Z0-9])$";
String toBeTested= "TesADAD2-3t?S+s/fs:fds'f.324,ffs";
boolean testResult= Pattern.matches(strRGEX, toBeTested);
System.out.println("Test="+testResult);