while (matcher.find()) {
if (matcher.group(matcherGroup) != null) occurrence++;
}
return occurrence;
This is the code that i am using to search for the number of matches of a certain group. However there is no function like matcher.group(matcherGroup1, matcherGroup2) nor there is matcher.group(null) to search for multiple groups or all groups.
I have read Link groups (its stupid to group the arrays into one) or multiple groups?
Thanks
Can you not write your own matcherGroup implementation? The link you have provided is c#.
I have written a simple Java implementation which takes a single string, and then matches it against multiple RegExp patterns. The number of matches are then returned.
Alternatively please explain in more detail what you are trying to do.
package com.chocksaway;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
class SingleMatcher {
private Pattern pattern;
private java.util.regex.Matcher matcher;
private boolean found;
SingleMatcher(String input, String inputPattern) {
pattern = Pattern.compile(inputPattern);
matcher = pattern.matcher(input);
if (matcher.find()) {
this.found = true;
}
}
boolean getFound() {
return this.found;
}
}
class MatcherGroup {
private int matchedOccurances;
MatcherGroup(String input, List<String> multipleInputPattern) {
for (String inputPattern : multipleInputPattern) {
SingleMatcher eachSingleMatcher = new SingleMatcher(input, inputPattern);
if (eachSingleMatcher.getFound()) {
matchedOccurances++;
}
}
}
int getMatchedOccurances() {
return this.matchedOccurances;
}
}
/**
* Author milesd on 28/05/2017.
*/
public class RegExpMatcher {
public static void main(String[] args) {
SingleMatcher singleMatcher = new SingleMatcher("123", "\\d\\d\\d");
System.out.println(singleMatcher.getFound());
List<String> inputPatternList = new ArrayList<String>();
inputPatternList.add("\\d\\d\\d");
inputPatternList.add("John");
MatcherGroup matcherGroup = new MatcherGroup("John", inputPatternList);
System.out.println(matcherGroup.getMatchedOccurances());
}
}
Related
Drools can return list of rules matched using below code but can it return ruleset in which no rules were matched or a list of rules not matched? If yes, how? In code, i want to know if no rules matched or executed in a particular ruleset.
import java.util.ArrayList;
import java.util.List;
import org.kie.api.event.rule.AfterMatchFiredEvent;
import org.kie.api.event.rule.DefaultAgendaEventListener;
import org.kie.api.runtime.rule.Match;
/**
* Wrapper to log matched rules for input request.
*
*/
public class DroolsResponseReader extends DefaultAgendaEventListener {
private List<Match> matchList = new ArrayList<Match>();
boolean isRuleFired() {
return matchList.size() > 0;
}
#Override
public void afterMatchFired(final AfterMatchFiredEvent event) {
matchList.add(event.getMatch());
}
public String rulesFiredToString() {
if(matchList.size() == 0) {
return "No Rule Fired!";
} else {
StringBuilder matches = new StringBuilder("Rule Fired : ");
for (Match match : matchList) {
matches.append("\nRule: ").append(match.getRule().getName());
}
return matches.toString();
}
}
I was able to get class level variable's declarations using the following code. But I only need the variable name. This is the output I get for following code - [private boolean flag = true;]
import com.github.javaparser.JavaParser;
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
import com.github.javaparser.ast.visitor.VoidVisitorAdapter;
import java.io.FileInputStream;
public class CuPrinter{
public static void main(String[] args) throws Exception {
// creates an input stream for the file to be parsed
FileInputStream in = new FileInputStream("C:\\Users\\arosh\\IdeaProjects\\Bot_Twitter\\src\\MyBot.java");
CompilationUnit cu;
try {
// parse the file
cu = JavaParser.parse(in);
} finally {
in.close();
}
cu.accept(new ClassVisitor(), null);
}
private static class ClassVisitor extends VoidVisitorAdapter<Void> {
#Override
public void visit(ClassOrInterfaceDeclaration n, Void arg) {
/* here you can access the attributes of the method.
this method will be called for all methods in this
CompilationUnit, including inner class methods */
System.out.println(n.getFields());
super.visit(n, arg);
}
}
}
You can use the following simple regex:
final String regex = "^((private|public|protected)?\\s+)?.*\\s+(\\w+);$";
Which then can be compiled into a Pattern:
final Pattern pattern = Pattern.compile(regex);
And then finally be used in a for-loop:
for(final String field : n.getFields()){
// create a regex-matcher
final Matcher matcher = pattern.matcher(field);
// if field matches regex
if(matcher.matches()){
// get the last group -> the fieldName
final String name = matcher.group(matcher.groupCount());
System.out.println("FieldName: " + name);
}
}
You can try this. If you have more than one variables in FieldDeclarations, use one more for loop inside.
public void visit(ClassOrInterfaceDeclaration n, Void arg) {
super.visit(n, arg);
for(FieldDeclaration ff:n.getFields())
{
System.out.println(ff.getVariable(0).getName());
}
}
sI use a simple text-file like this
BMG-P (someLongComplicatedExpression)(.*P)
BMG T (someLongComplicatedExpression)(.*[Tt])
BMG MPA (someLongComplicatedExpression)(.*MPA)
to configure my application (Simple import with bufferedReader.readLine().split("\t")). What is bugging me is the redundance.
I am thinking about a solution like this:
%s=(someLongComplicatedExpression)
BMG-P %s(.*P)
BMG T %s(.*[Tt])
BMG MPA %s(.*MPA)
where I read the value of my variables (like %s), then replace their occurrences in the Strings after the import.
My questions are:
What alternative approaches do you know?
What is an easy way to implement the replacement of my variables in my code?
Can you point me to any frameworks that support property-files like that?
I wrote this simple extension to the Java Properties class:
import java.io.Serializable;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Allows properties to contain expansions of the form ${propertyName}. This
* class makes no attempt to detect circular references, so be careful.
*/
public class ExpandingProperties extends Properties implements PropertySource {
private static final long serialVersionUID = 259782782423517925L;
private final Expander expander = new Expander();
#Override
public String getProperty(String key) {
return expander.expand(super.getProperty(key), this);
}
}
class Expander implements Serializable {
private static final long serialVersionUID = -2229337918353092460L;
private final Pattern pattern = Pattern.compile("\\$\\{([^}]+)\\}");
/**
* Expands variables of the form "${variableName}" within the
* specified string, using the property source to lookup the
* relevant value.
*/
public String expand(final String s, final PropertySource propertySource) {
if (s == null) {
return null;
}
final StringBuffer sb = new StringBuffer();
final Matcher matcher = pattern.matcher(s);
while (matcher.find()) {
final String variableName = matcher.group(1);
final String value = propertySource.getProperty(variableName);
if (value == null) {
throw new RuntimeException("No property found for: " + variableName);
}
matcher.appendReplacement(sb, value.replace("$", "\\$"));
}
matcher.appendTail(sb);
return sb.toString();
}
}
interface PropertySource {
String getProperty(String key);
}
Example usage:
public static void main(String[] args) {
Properties properties = new ExpandingProperties();
properties.put("myVar", "myLongExpression");
properties.put("foo", "${myVar}_1");
properties.put("bar", "${foo}_abc");
System.out.println(properties.getProperty("bar"));
}
Prints:
myLongExpression_1_abc
As ExpandingProperties is an extension of Properties it inherits all the load...() methods for loading values from property files.
An alternative is EProperties which does a similar thing to the above code, but goes even further and allows you to nest property files etc. I found it overkill for what I needed.
I need to use a replace function in Java:
string.replace(myString,"");
myString values are for example javascript:r(0), javascript:r(23), javascript:l(5) etc. Just number is always different and there is r or l letter. What's the regular expression to match it? Thanks
(FIXED) The regex you want is
"javascript:[rl]\\(\\d+\\)"
NOTE: The outer quotes aren't really part of the regex; they are part of the Java string you pass to Pattern.compile or directly to replace.
Here is a complete program you can try:
import java.util.regex.Pattern;
import java.util.regex.Matcher;
public class PatternExample {
private static final Pattern JS_PATTERN = Pattern.compile("javascript:[rl]\\(\\d+\\)");
private static final String[] MESSAGES = {
"Good javascript:r(5)",
"Good javascript:l(50003843)",
"Good javascript:r(1123934)",
"Bad javascript:|(5)",
"Bad javascript:r(53d)",
"Bad javascript:l()",
};
public static void main(String[] args) {
for (String s : MESSAGES) {
Matcher matcher = JS_PATTERN.matcher(s);
System.out.println(matcher.replaceAll(""));
}
}
}
Here is another version of the above program that calls replaceAll directly on the string instead of pre-compiling the pattern:
public class PatternExample {
private static final String[] MESSAGES = {
"Good javascript:r(0)",
"Good javascript:l(50003843)",
"Good javascript:r(1123934)",
"Bad javascript:|(5)",
"Bad javascript:r(53d)",
"Bad javascript:l()",
};
public static void main(String[] args) {
for (String s : MESSAGES) {
System.out.println(s.replaceAll("javascript:[rl]\\(\\d+\\)", ""));
}
}
}
The following regex will match it:
javascript:[rl]\(\d+\)
I use a jFormattedTextField for a telephone number and only to accept the numeric values i
declare it as "new NumberFormatterFactory(Integer.class, false)" .
Now the problem is when the number starts with 0(zero) like 001345.. , after entered the value and moved to next column the entered value is trimmed as 1345.. here it not accepting the 0 as the starting number.
how can I enter the number starts with 0
Yeah, telephone numbers are slightly different from integers in that sense.
Following this example at you could solve it using regular expressions like this:
import java.text.ParseException;
import java.util.regex.*;
import javax.swing.*;
import javax.swing.text.DefaultFormatter;
class RegexFormatter extends DefaultFormatter {
private Pattern pattern;
private Matcher matcher;
public RegexFormatter() {
super();
}
public RegexFormatter(String pattern) throws PatternSyntaxException {
this();
setPattern(Pattern.compile(pattern));
}
public RegexFormatter(Pattern pattern) {
this();
setPattern(pattern);
}
public void setPattern(Pattern pattern) {
this.pattern = pattern;
}
public Pattern getPattern() {
return pattern;
}
protected void setMatcher(Matcher matcher) {
this.matcher = matcher;
}
protected Matcher getMatcher() {
return matcher;
}
public Object stringToValue(String text) throws ParseException {
Pattern pattern = getPattern();
if (pattern != null) {
Matcher matcher = pattern.matcher(text);
if (matcher.matches()) {
setMatcher(matcher);
return super.stringToValue(text);
}
throw new ParseException("Pattern did not match", 0);
}
return text;
}
}
public class Test {
public static void main(String[] a) {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JFormattedTextField formattedField =
new JFormattedTextField(new RegexFormatter("\\d*"));
frame.add(formattedField, "North");
frame.add(new JTextField(), "South");
frame.setSize(300, 200);
frame.setVisible(true);
}
}
If you declare it as new NumberFormatterFactory(Integer.class, false) which is for only Integer, 0 wont be considered. You need to change it to other formatter and not store Phone Number as number (i.e. Integer).
Check this example for phone number formatting:
http://www.java2s.com/Code/Java/Swing-JFC/JFormattedTextFieldaninputmaskforatelephonenumber.htm
http://www.ibm.com/developerworks/java/library/j-mer0625/index.html