I need to count all valid if statements in a .java file (not commented etc)
I was trying to modify regex for commented items:
(?:/\\*(?:[^*]|(?:\\*+[^*/]))*\\*+/)|(?://.*)
and came up with smth like this:
(?!(([\\(])|(/\\*)|(//)))((?=\\s*))(if)(?=[\\s\\(])
But it doesnt work correctly
Im using this code for test input:
public class Main () {
public static void main (String[] args) {
boolean ifTrue = true;
if (ifTrue == true) {
String wariant = "wariant";
} else if (ifTrue == false) {
String dupa = "variant";
}
//if(ifTrue == true) {
String wariant2 = "This is second wariant";
//}
if(ifTrue) {
if(ifTrue) {
} else if (ifTrue) {
//if ()
/**if*/
}
}
/*if(ifTrue == true) {
String wariant2 = "To jest wariant 2";
}*/
}
}
And this function for counting:
private static int countRegexInInput(String regex, String input) {
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
int count = 0;
while (matcher.find()) {
count++;
}
return count;
}
For the current sample code , and just counting IF Statements:
/(?:^|\}\s*else)\s+\bif\b/gm
This regex match IF Statements that seems valid. (SEE DEMO)
If your Input texts are general and complex that contains this example:
/* some comments!
if (condition) {
}
*/
use this version:(SEE DEMO)
(?:(?:\/\*)[^]*?\*\/|^)[\s\S]*?(?:^|\}?\s*else)\s*\bif\b
^^1 ^^^^^^^^^^^^^^^2 ^^^^^^3 ^^^^^^^^^^^^^^^^^^^4
Description:
1- match every thing that is Group 2 or is new line ^.
2- find /* and count capturing to */
3- match and pass characters until find new IF
4- IF statement followed by one/many spaces after ^ or after else.
Note: this regex pattern can improve for better matching, if this is not enough!
Well this regex seems to be working for my case:
([^e]\\s)(if)(\\s?\\((\\D[^\\)]+)\\))
Related
I am writing a program and want the program to not loop and request another search pattern if the search pattern (word) contains any non alpha numeric characters.
I have setup a Boolean word to false and an if statement to change the Boolean to true if the word contains letters or numbers. Then another if statement to allow the program to execute if the Boolean is true.
My logic must be off because it is still executing through the search pattern if I simply enter "/". The search pattern cannot contain any non alpha numeric characters to include spaces. I am trying to use Regex to solve this problem.
Sample problematic output:
Please enter a search pattern: /
Line number 1
this.a 2test/austin
^
Line number 8
ra charity Charityis 4 times a day/a.a-A
^
Here is my applicable code:
while (again) {
boolean found = false;
System.out.printf("%n%s", "Please enter a search pattern: ", "%n");
String wordToSearch = input.next();
if (wordToSearch.equals("EINPUT")) {
System.out.printf("%s", "Bye!");
System.exit(0);
}
Pattern p = Pattern.compile("\\W*");
Matcher m = p.matcher(wordToSearch);
if (m.find())
found = true;
String data;
int lineCount = 1;
if (found = true) {
try (FileInputStream fis =
new FileInputStream(this.inputPath.getPath())) {
File file1 = this.inputPath;
byte[] buffer2 = new byte[fis.available()];
fis.read(buffer2);
data = new String(buffer2);
Scanner in = new Scanner(data).useDelimiter("\\\\|[^a-zA-z0-9]+");
while (in.hasNextLine()) {
String line = in.nextLine();
Pattern pattern = Pattern.compile("\\b" + wordToSearch + "\\b");
Matcher matcher = pattern.matcher(line);
if (matcher.find()) {
System.out.println("Line number " + lineCount);
String stringToFile = f.findWords(line, wordToSearch);
System.out.println();
}
lineCount++;
}
}
}
}
Stop reinventing the wheel.
Read this: Apache StringUtils,
Focus on isAlpha,
isAlphanumeric,
and isAlphanumericSpace
One of those is likely to provide the functionality you want.
Create a separate method to call the String you are searching through:
public boolean isAlphanumeric(String str)
{
char[] charArray = str.toCharArray();
for(char c:charArray)
{
if (!Character.isLetterOrDigit(c))
return false;
}
return true;
}
Then, add the following if statement to the above code prior to the second try statement.
if (isAlphanumeric(wordToSearch) == true)
Well since no one posted REGEX one, here you go:
package com.company;
public class Main {
public static void main(String[] args) {
String x = "ABCDEF123456";
String y = "ABC$DEF123456";
isValid(x);
isValid(y);
}
public static void isValid(String s){
if (s.matches("[A-Za-z0-9]*"))
System.out.println("String doesn't contain non alphanumeric characters !");
else
System.out.println("Invalid characters in string !");
}
}
Right now, what's happening is if the search pattern contains non alphanumeric characters, then do the loop. This is because found = true when the non alphanumeric characters are detected.
if(m.find())
found = true;
What it should be:
if(!m.find())
found = true;
It should be checking for the absence of nonalphanumeric characters.
Also, the boolean flag can just be simplified to:
boolean found = !m.find();
You don't need to use the if statement.
My file (rates.txt) contains: Abc defghijk lmn opqr st uvwxyza bc 19
I want to extract only the 19 from the file and store it as an integer.
How do I go about this?
I've tried using a substring but am unsure what method to use in order to make it select only the numerical value.
Thanks
What if you use a regular expression.
Try this (I assumed you only have one integer value):
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Tester {
public static void main(String[] args) {
Pattern pattern = Pattern.compile("\\D*(\\d+)\\D*");
Matcher matcher = pattern.matcher("Abc defghijk lmn opqr st uvwxyza bc 19");
try {
if (matcher.find()) {
String stringDigit = matcher.group(1);
int number = Integer.parseInt(stringDigit);
System.out.println(number);
}
} catch(Exception e) {
}
}
}
The pattern "\D*(\d+)\D*" actually means:
\D*: multiple non-digit characters (including zero amount of character)
\d+: multiple digit characters
So, we are searching some digit characters enclosed by some non-digit characters.
Pattern.compile("\\D*(\\d+)\\D*");
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
public static void main(String[] args) {
String text = "xAbc defghijk lmn opqr st uvwxyza bc 19";
Pattern pattern = Pattern.compile("([0-9]+)");
Matcher matcher = pattern.matcher(text);
if(matcher.find()) {
int number = Integer.valueOf(matcher.group(1));
System.out.println("First number: "+number);
}
else {
System.out.println("Not found");
}
}
}
Loop through each line within the file.
To do so you can use Iterator and its method hasNext()
Once you've retrieved a line, split it by the empty spaces as follows:
String str = "";
List< String> splitElements = Arrays.asList(str.split("\s+"));
Afterwards, loop through each element of the list and it'd be a good idea to create a helperMethod in charge of verifying whether an element is number or not. It could be achieved with something like this:
public static boolean isNumeric(String string) {
try
{
int intString = Integer.parseInt(string);
}
catch(NumberFormatException ex)
{
return false;
}
return true;
}
Make notice that it parses just int numbers, create more helper methods and you're done, hope it helps!
I am trying to censor specific strings, and patterns within my application but my matcher doesn't seem to be finding any results when searching for the Pattern.
public String censorString(String s) {
System.out.println("Censoring... "+ s);
if (findPatterns(s)) {
System.out.println("Found pattern");
for (String censor : foundPatterns) {
for (int i = 0; i < censor.length(); i++)
s.replace(censor.charAt(i), (char)42);
}
}
return s;
}
public boolean findPatterns(String s) {
for (String censor : censoredWords) {
Pattern p = Pattern.compile("(.*)["+censor+"](.*)");//regex
Matcher m = p.matcher(s);
while (m.find()) {
foundPatterns.add(censor);
return true;
}
}
return false;
}
At the moment I'm focusing on just the one pattern, if the censor is found in the string. I've tried many combinations and none of them seem to return "true".
"(.*)["+censor+"](.*)"
"(.*)["+censor+"]"
"["+censor+"]"
"["+censor+"]+"
Any help would be appreciated.
Usage: My censored words are "hello", "goodbye"
String s = "hello there, today is a fine day."
System.out.println(censorString(s));
is supposed to print " ***** today is a fine day. "
Your regex is right!!!!. The problem is here.
s.replace(censor.charAt(i), (char)42);
If you expect this line to rewrite the censored parts of your string it will not. Please check the java doc for string.
Please find below the program which will do what you intend to do. I removed your findpattern method and just used the replaceall with regex in String API. Hope this helps.
public class Regex_SO {
private String[] censoredWords = new String[]{"hello"};
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
Regex_SO regex_SO = new Regex_SO();
regex_SO.censorString("hello there, today is a fine day. hello again");
}
public String censorString(String s) {
System.out.println("Censoring... "+ s);
for(String censoredWord : censoredWords){
String replaceStr = "";
for(int index = 0; index < censoredWord.length();index++){
replaceStr = replaceStr + "*";
}
s = s.replaceAll(censoredWord, replaceStr);
}
System.out.println("Censored String is .. " + s);
return s;
}
}
Since this seem like homework I cant give you working code, but here are few pointers
consider using \\b(word1|word2|word3)\\b regex to find specific words
to create char representing * you can write it as '*'. Don't use (char)42 to avoid magic numbers
to create new string which will have same length as old string but will be filled with only specific characters you can use String newString = oldString.replaceAll(".","*")
to replace on-the-fly founded match with new value you can use appendReplacement and appendTail methods from Matcher class. Here is how code using it should look like
StringBuffer sb = new StringBuffer();//buffer for string with replaced values
Pattern p = Pattern.compile(yourRegex);
Matcher m = p.matcher(yourText);
while (m.find()){
String match = m.group(); //this will represent current match
String newValue = ...; //here you need to decide how to replace it
m.appentReplacemenet(sb, newValue );
}
m.appendTail(sb);
String censoredString = sb.toString();
In Java, how would I get a substring of a certain character followed by a number?
The string looks like this:
To be, or not to be. (That is the question.) (243)
I want the substring up until the (243), where the number inside the parenthesis is always changing every time I call.
Use a regular expression:
newstr = str.replaceFirst("\(\d+\)", "");
What this means is to find a substring beginning with (, then any number of digits, and then the character ). Then replace the substring with the empty string, "".
Reference: java.lang.String.replaceFirst()
You could match it with a regex, and get the index of the regex. Then use that to get the index in the string.
An example of that is Can Java String.indexOf() handle a regular expression as a parameter?
Pattern pattern = Pattern.compile(patternStr);
Matcher matcher = pattern.matcher(inputStr);
if(matcher.find()){
System.out.println(matcher.start());//this will give you index
}
You can use String.replaceAll():
String s = "To be, or not to be. (That is the question.) (243)";
String newString = s.replaceAll("\\(\\d+\\).*", "");
I think you can actually just do something like:
mystring.substring(0,mystring.lastIndexOf"("))
assuming that the last thing on the line will be the number in parentheses.
You could use a for loop and add the characters before the number to a separate string
String sentence = "To be, or not to be. (That is the question.) (243)";
public static void main(String[] args) {
String subSentence = getSubsentence(sentence);
}
public String getSubsentence(String sentence) {
String subSentence = "";
boolean checkForNum = false;
for (int i = 0; i < sentence.length(); i++) {
if (checkForNum) {
if (isInteger(sentence.getSubstring(i, i+1))) return subSentence;
checkForNum = false;
} else {
if (sentence.getSubstring(i, i+1).equals("(")) checkForNum = true;
else subSentence += sentence.getSubstring(i, i+1);
}
}
return subSentence;
}
public boolean isInteger(String s) {
try {
Integer.parseInt(s);
} catch(NumberFormatException e) {
return false;
}
return true;
}
Using a regex this can be solved with.
public class RegExParser {
public String getTextPart(String s) {
String pattern = "^(\\D+)(\\s\\(\\d+\\))$";
String part = s.replaceAll(pattern, "$1");
return part;
}
}
Simple and performance is good.
I've got the following code:
public class testMatch {
public static void main(String[] args) {
String dummyMessage = "asdfasdfsadfsadfasdf 3 sdfasdfasdfasdf";
String expression = "3";
if (dummyMessage.matches(expression)){
System.out.println("MATCH!");
} else {
System.out.println("NO MATCH!");
}
}
}
I'd expect this to be a successful match as the dummyMessage contains the expression 3 but when I run this snippet the code prints NO MATCH!
I don't get what I'm doing wrong.
OKAY STOP ANSWERING! .*3.* works
This is an over simplification of an issue I have in some live code, the regex is configurable, and up until now matching the entire string has been okay, I've now had to match a part of the string and was wondering why it wasn't working.
It matches against the whole string, i.e. like ^3$ in most other regex implementations. So 3 does not match e.g. 333 or your string. But .*3.* would do the job.
However, if you just want to test if "3" is contained in your string you don't need a regex at all. Use dummyMessage.contains(expression) instead.
String#matches(regex) Tells whether or not this string matches the given regular expression.
your string dummyMessage doesn't match expression, as it tries to check if dummyMessage is 3 you probably want String.contains(charseq) instead.
String dummyMessage = "asdfasdfsadfsadfasdf 3 sdfasdfasdfasdf";
String expression = "3";
if (dummyMessage.contains(expression)){
System.out.println("MATCH!");
} else {
System.out.println("NO MATCH!");
}
You should match the whole string for matches to return true. Maybe try using .*3.*.
It will match for such regex: .*3.*
Use contains(expression)
String dummyMessage = "asdfasdfsadfsadfasdf 3 sdfasdfasdfasdf";
String expression = "3";
if (dummyMessage.contains(expression)) {
System.out.println("MATCH!");
} else {
System.out.println("NO MATCH!");
}
By default String#matches() test if string matches regular expression completely. To make it working replace
expression = "3"
with
expression = ".*3.*"
To match substring in string use Matcher#find() method.
your regexp should rather be .*3.*
the matches() method on String class check if the whole string matches.
I modified your code to:
public class testMatch
{
public static void main(String[] args)
{
String dummyMessage = "asdfasdfsadfsadfasdf 3 sdfasdfasdfasdf";
String expression = ".*3.*";
if (dummyMessage.matches(expression))
{
System.out.println("MATCH!");
}
else
{
System.out.println("NO MATCH!");
}
}
}
and it now works
You may be looking for matcher.find:
String message = "asdfasdfsadfsadfasdf 3 sdfasdf3asdfasdf";
String expression = "3";
// Really only need to do this once.
Pattern pattern = Pattern.compile(expression);
// Do this once for each message.
Matcher matcher = pattern.matcher(message);
if (matcher.find()) {
do {
System.out.println("MATCH! At " + matcher.start() + "-" + matcher.end());
} while ( matcher.find() );
} else {
System.out.println("NO MATCH!");
}
Change the original regex accordingly - it is currently incorrect and does not match:
String expression = "(.*)3(.*)";
Or just use String.contains() - I'd say that is a lot more appropriate for this situation.
Either you do it that way:
String dummyMessage = "asdfasdfsadfsadfasdf 3 sdfasdfasdfasdf";
String expression = "3";
Pattern p = Pattern.compile(".*3.*");
Matcher m = p.matcher(dummyMessage);
boolean b = m.matches();
if (b) {
System.out.println("MATCH!");
}
else {
System.out.println("NO MATCH!");
}
Or this way:
String dummyMessage = "asdfasdfsadfadfasdf 3 sdfasdfasdfasdf";
String expression = "3"
if (dummyMessage.contains(expression)) {
System.out.println("MATCH!");
}
else {
System.out.println("NO MATCH!");
}