How to Set Multple Regex Costraints on textbox in ZKOSS - regex

I have a textbox which should only accept Characters:-for that first regex has been set in constraint and it should not accept some reserved keywords that are A,R,F,U .Since two different constraints are set ,i want user to see the specific message ,for first it should be Illegal Value i.e default zkoss error and when he/she enters a reserved character ,it should show that reserved code has been put.
But somehow the following code doesnt work :
field_code.setConstraint("/[a-zA-Z]/ : {Illegal Value} ,/[^AaRrUuFf]/ : Reserved Code");
The output is the first regex works fine but on offending the same " {Illegal Value} ,/[^AaRrUuFf]/ : Reserved Code" is displayed as error.

You can't do it in the zul, but with help of a SimpleConstraint you could create this.
Create your own class, and extend SimpleConstraint.
Then hold 2 Matcher vars for each constraint.
At last, override the Validate method to something like this :
#Override
public void validate(Component comp, Object value) {
if (value != null && value instanceof String) {
String stringValue = (String) value;
if (!expression1.reset(stringValue).matches()) {
throw new WrongValueException(comp, errorMsg1);
}
if (!expression2.reset(stringValue).matches()) {
throw new WrongValueException(comp,errorMsg2);
}
} else {
// do what needs to be done when value is null or not a String.
}
}

Related

How to iterate a class?

UPDATES
This is my final codes just in case anyone needs it:
int index = -2; //I am not 100% sure why I need to start -2, but I assume that `forEach((item){})` probably increase `index` by one, and I also increase `index` inside of the loop, so that's probably why.
recyclable.forEach((item) {
index++;
if (item.title == _outputs[0]["label"]) {
//your code for when the match is found
//move to the detailed page to show more description
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DetailScreen(recyclable: recyclable[index]),
),
);
}
}
END OF UPDATES
I created a class named Recyclable, and using the class, I created a list named recyclable. The list recyclable has a string named title, and I am trying to iterate that title to find a match with _outputs[0]["label"].
To do it, I tried the following code:
while (_outputs[0]["label"] != recyclable[index].title) {
index++;
}
Somehow, there was a red underline for index, which I have no idea why.
I also tried for loop as below to remove that red underline by removing index from my code:
for (var _outputs[0]["label"] in recyclable.title) {
index++;
}
But the code seems to be completely off.
FYI, Here is my class Recyclable:
class Recyclable {
final String title;
final String description;
final String instruction;
final String why;
final String
recycle; //put either "recyclable" or "not recyclable" (This item "can be recycled")
final String
donate; //put either "can be donated" or "cannot be donated" (This item "can be donated")
Recyclable(this.title, this.description, this.instruction, this.why,
this.recycle, this.donate);
}
And here is the list:
List<Recyclable> recyclable = [
Recyclable('PAPERS', 'abc2', 'instruction123', 'why123', 'recyclable',
'cannot be donated'),
Recyclable('CLOTHING', 'abc3', 'instruction123', 'why123', 'recyclable',
'can be donated'),
Recyclable('CARDBOARDS', 'abc4', 'instruction123', 'why123',
'can be recycled', 'cannot be donated'),
Recyclable('COMPUTERS', 'abc4', 'instruction123', 'why123', 'recyclable',
'can be donated'),
];
One way you can iterate over the recyclable list is like this using forEach method
recyclable.forEach((item){
if(item.title == _outputs[0]["label"]){
//your code for when the match is found
}
});

Regex to match sub string of a string

I need to construct a regular expression to match a given value to the brand field of my product array. For instance, given the parameter "am", an array of the following products would be returned: [Amana, Mama, etc]. How do I complete this function?
public searchProduct(term) {
this.products.forEach(product => {
if (product.brand.match(`${term}`)) {
console.log('mtch found', product.brand)
}
});
return of(this.products)
}
Unless you have some special reasons to use regex, you can use filter and includes to return only items of your array containing your substring
public searchProduct(term) {
return this.products.filter(x => x.brand.includes(term))
}

How to find matches that occur within a specified string with regex?

I have a unique situation where I need to query a mongo database to find the names of people who occur in a body of text. The query must specify the body of text and find records with values that occur in the body of text. How can I do this with a regular expression?
I need to write a query where this would match:
/Jonathan is a handsome guy/.test('Jonathan')
The problem is that the text inside "test" is the value of a mongo field, so this query must be written such that the body of text is provided as input, and it matches on names that occur within (are substrings of) the body of text.
A more concrete example:
db.test.find();
{ "_id" : ObjectId("547e9b79f2b519cd1657b21e"), "name" : "Jonathan" }
{ "_id" : ObjectId("547e9b88f2b519cd1657b21f"), "name" : "Sandy" }
db.test.find({name: { $in: [/Jonathan has the best queries/]} } );
I need to construct a query that would return "Jonathan" when provided the input "Jonathan has the best queries"
This $where may do the trick, though can be very slow:
db.test.find({$where: function() {
var mystr = '/Jonathan has the best queries/';
var patt = new RegExp(this.name);
if (patt.test(mystr)) return true;
return false;
}})

String replace with dictionary exception handling

I've implemented the answer here to do token replacements of a string:
https://stackoverflow.com/a/1231815/1224021
My issue now is when this method finds a token with a value that is not in the dictionary. I get the exception "The given key was not present in the dictionary." and just return the normal string. What I'd like to happen obviously is all the good tokens get replaced, but the offending one remains au naturale. Guessing I'll need to do a loop vs. the one line regex replace? Using vb.net. Here's what I'm currently doing:
Shared ReadOnly re As New Regex("\$(\w+)\$", RegexOptions.Compiled)
Public Shared Function GetTokenContent(ByVal val As String) As String
Dim retval As String = val
Try
If Not String.IsNullOrEmpty(val) AndAlso val.Contains("$") Then
Dim args = GetRatesDictionary()
retval = re.Replace(val, Function(match) args(match.Groups(1).Value))
End If
Catch ex As Exception
' not sure how to handle?
End Try
Return retval
End Function
The exception is likely thrown in the line
retval = re.Replace(val, Function(match) args(match.Groups(1).Value))
because this is the only place you are keying the dictionary. Make use of the Dictionary.ContainsKey method before accessing it.
retval = re.Replace(val,
Function(match)
return If(args.ContainsKey(match.Groups(1).Value), args(match.Groups(1).Value), val)
End Function)
This is what I got to work vs. the regex, which was also a suggestion on the original thread by Allen Wang: https://stackoverflow.com/a/7957728/1224021
Public Shared Function GetTokenContent(ByVal val As String) As String
Dim retval As String = val
Try
If Not String.IsNullOrEmpty(val) AndAlso val.Contains("$") Then
Dim args = GetRatesDictionary("$")
retval = args.Aggregate(val, Function(current, value) current.Replace(value.Key, value.Value))
End If
Catch ex As Exception
End Try
Return retval
End Function
I know it's been a while since this question was answered, but FYI for anyone wanting to still use the Regex / Dictionary match approach, the following works (based on the sample in the OP question):
retVal = re.Replace(formatString,
match => args.ContainsKey(match.Groups[1].Captures[0].Value)
? args[match.Groups[1].Captures[0].Value]
: string.Empty);
... or my full sample as a string extension method is:
public static class StringExtensions
{
// Will replace parameters enclosed in double curly braces
private static readonly Lazy<Regex> ParameterReplaceRegex = new Lazy<Regex>(() => new Regex(#"\{\{(?<key>\w+)\}\}", RegexOptions.Compiled));
public static string InsertParametersIntoFormatString(this string formatString, string parametersJsonArray)
{
if (parametersJsonArray != null)
{
var deserialisedParamsDictionary = JsonConvert.DeserializeObject<Dictionary<string, string>>(parametersJsonArray);
formatString = ParameterReplaceRegex.Value.Replace(formatString,
match => deserialisedParamsDictionary.ContainsKey(match.Groups[1].Captures[0].Value)
? deserialisedParamsDictionary[match.Groups[1].Captures[0].Value]
: string.Empty);
}
return formatString;
}
}
There are a few things to note here:
1) My parameters are passed in as a JSON array, e.g.: {"ProjectCode":"12345","AnotherParam":"Hi there!"}
2) The actual template / format string to do the replacements on has the parameters enclosed in double curly braces: "This is the Project Code: {{ProjectCode}}, this is another param {{AnotherParam}}"
3) Regex is both Lazy initialized and Compiled to suit my particular use case of:
the screen this code serves may not be used often
but once it is, it will get heavy use
so it should be as efficient on subsequent calls as possible.

How set a copy field with Boolean value base on other field in SOLR?

I defined a copyField and called it:"IsIntranet" and i know my users in intranet using 192.168.* Ip
I wanna set value true if my regex matched in IsIntranet copy field and if not i set false to that
this is my regex (192\.168\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))
how can i do such a thing?
If you need any more information i can Edit my Question.
Thank you.
It seems you are looking for a conditional copyField.
You can do this by creating a subclass of UpdateRequestProcessorFactory.
You can then override the processAdd method to add to your isIntranet field if it matches the regex.
public void processAdd(AddUpdateCommand cmd) throws IOException {
SolrInputDocument doc = cmd.getSolrInputDocument();
Object v = doc.getFieldValue( "ip" );
if( v != null ) {
String regexPattern = "(192\.168\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))"
if( Pattern.matches(regexPattern, v) ) {
doc.addField( "IsIntranet", true );
}
}
super.processAdd(cmd);
}
You can find the whole example here.