Is there a way to define rewrite rules in OCPSoft rewrite independent of case instead of defining multiple rules, since any character could be lower or upper case?
cb.addRule(Join.path('/Test').to("/test.xhtml"));
cb.addRule(Join.path('/test').to("/test.xhtml"));
Something like:
boolean ignoreCase = true;
cb.addRule(Join.path('/Test', ignoreCase).to("/test.xhtml"));
Background:
Logging our 404 errors i encounter a lot of requests just with lower case URLs.
Yes! Absolutely.
The simplest way to do this is probably use a parameter with a regex .matches() constraint:
cb.addRule(
Join.path('/{path}').to("/test.xhtml"))
.where("path")
.matches("(?i)test"); // <-- your path regex pattern goes here
You could also use the Resource or Filesystem condition with a custom transform to make this a more global rule:
public class Lowercase implements Transposition<String>
{
#Override
public String transpose(Rewrite event, EvaluationContext context, String value)
{
return value.toLowerCase();
}
}
Then...
.addRule(Join.path("/{path}").to("/{path}.xhtml"))
.when(Resource.exists("{path}.xhtml"))
.where("path")
.matches("[a-zA-Z]+")
.transposedBy(new Lowercase())
This of course assumes that your xhtml files all use a lowercase naming scheme.
You could create your own custom .when() conditions to locate the most likely matches, then substitute the 'found / correct' value of {path} in the transposition, if you wanted to go even farther.
Related
Let's imagine I have log file like the following:
My custom exception ST: java.lang.RuntimeException: Text of this dummy err.
My final goal is to put everything after ST: to new field ST called and remove ST:.
I'm trying to use the pattern, but it doesn't work.
filter {
grok {
match => { "message" => "(?<newField>(?<=ST)(?s)(.*$))" }
}
Grok is based on Oniguruma regex library. To make . match any char with an Oniguruma regex, you need to pass (?m) inline modifier, not (?s) (as in PCRE and some other regex engines).
By placing (?<=ST) positive lookahead inside the named capturing group, you require ST to appear immediately before the current location, but you have ST and a colon right after, and then a space. It makes sense to just move ST: out of the named group:
"(?m)ST: (?<newField>.*)"
^^^^^^^^
The ST: and space will get matched and consumed, newField group will hold the rest of string in it.
You can use a specific regex like that:
^My custom exception ST: %{GREEDYDATA:ST}
Or a more generric one:
%{GREEDYDATA} \bST\b: %{GREEDYDATA:ST}
Always try to use specific regex.
I am testing a string that contains an identifier for which type of device submitted the string. The device type identifier will be something like "123456**FF789000AB" where the * denote any character could be used at this position. I run a series of functions to parse additional data and set variables based on the type of device submitting the data. Currently, I have the following statement:
if (payload[4].includes("02010612FF590080BC")) { function(topic, payload, intpl)};
The string tested in the includes() test will always start with 020106, but the next two characters could be anything. Is there a quick regex I could throw in the includes function, or should I organize the test in a different way?
To match the "020106**FF590080BC" pattern, where * can be anything, you can use RegExp.test() and the regular expression /020106..FF590080BC/:
if (/020106..FF590080BC/.test(payload[4])) { ... }
Also, if you require that the pattern must match the beginning of the string:
if (/^020106..FF590080BC/.test(payload[4])) { ... }
I'm trying to make this work, and it seems not to be accepted. Is there any fix, or workaround to it?
switch(email){
case (email.contains('acceptall')):
log.info email
break
default:
log.info "Doesn't work!"
}
I'm using groovy for a script in SoapUI
Use a regex, roughly:
switch (email) {
case ~/.*acceptall.*/:
log.info(email)
break;
default:
log.info("Doesn't work!")
}
http://groovy.codehaus.org/Logical+Branching#LogicalBranching-switchstatement
Switch supports the following kinds of comparisons
Class case values matches if the switchValue is an instanceof the
class
Regular expression case value matches if the string of the
switch
Value matches the regex Collection case value matches if the
switch
Value is contained in the collection. This also includes ranges
too (since they are Lists)
if none of the above are used then the case
value matches if the case value equals the switch value
you almost got it right, just need to turn it into a closure e.g.
switch (email) {
case { it.contains('acceptall') }:
log.info(email)
break;
default:
log.info("Doesn't work!")
}
Is it possible to split string into lexems somehow like
"user#domain.com" match {
case name :: "#" :: domain :: "." :: zone => doSmth(name, domain, zone)
}
In other words, on the same manner as lists...
Yes, you can do this with Scala's Regex functionality.
I found an email regex on this site, feel free to use another one if this doesn't suit you:
[-0-9a-zA-Z.+_]+#[-0-9a-zA-Z.+_]+\.[a-zA-Z]{2,4}
The first thing we have to do is add parentheses around groups:
([-0-9a-zA-Z.+_]+)#([-0-9a-zA-Z.+_]+)\.([a-zA-Z]{2,4})
With this we have three groups: the part before the #, between # and ., and finally the TLD.
Now we can create a Scala regex from it and then use Scala's pattern matching unapply to get the groups from the Regex bound to variables:
val Email = """([-0-9a-zA-Z.+_]+)#([-0-9a-zA-Z.+_]+)\.([a-zA-Z]{2,4})""".r
Email: scala.util.matching.Regex = ([-0-9a-zA-Z.+_]+)#([-0-9a-zA-Z.+_]+)\.([a-zA-Z] {2,4})
"user#domain.com" match {
case Email(name, domain, zone) =>
println(name)
println(domain)
println(zone)
}
// user
// domain
// com
Starting Scala 2.13, it's possible to pattern match a Strings by unapplying a string interpolator:
val s"$user#$domain.$zone" = "user#domain.com"
// user: String = "user"
// domain: String = "domain"
// zone: String = "com"
If you are expecting malformed inputs, you can also use a match statement:
"user#domain.com" match {
case s"$user#$domain.$zone" => Some(user, domain, zone)
case _ => None
}
// Option[(String, String, String)] = Some(("user", "domain", "com"))
In general regex is horribly inefficient, so wouldn't advise.
You CAN do it using Scala pattern matching by calling .toList on your string to turn it into List[Char]. Then your parts name, domain and zone will also be List[Char], to turn them back into Strings use .mkString. Though I'm not sure how efficient this is.
I have benchmarked using basic string operations (like substring, indexOf, etc) for various use cases vs regex and regex is usually an order or two slower. And of course regex is hideously unreadible.
UPDATE: The best thing to do is to use Parsers, either the native Scala ones, or Parboiled2
For example groovy converts getSomeProperty() method to someProperty.
I need the same for my string. prefixMyString converted to myString.
Is there standard way to do so?
Groovy doesn't actually convert getSomeProperty() into someProperty. It only converts the other way, turning someProperty into getSomeProperty()
It does this using the capitalize(String property) method on org.codehaus.groovy.runtime.MetaClassHelper. You can run this in the console to see it work:
org.codehaus.groovy.runtime.MetaClassHelper.capitalize('fredFlinstone')
// outputs 'FredFlintstone'
The full conversion, including adding set, get, or is, can be found in the class groovy.lang.MetaProperty, under the methods getGetterName and getSetterName.
To convert the other way, you'll have to write your own code. However, that's relatively simple:
def convertName(String fullName) {
def out = fullName.replaceAll(/^prefix/, '')
out[0].toLowerCase() + out[1..-1]
}
println convertName('prefixMyString') // outputs: myString
println convertName('prefixMyOTHERString') // outputs: myOTHERString
Just change the prefix to meet your needs. Note that it's a regex, so you have to escape it.
EDIT: I made a mistake. There actually is a built-in Java method to decapitalize, so you can use this:
def convertName(String fullName) {
java.beans.Introspector.decapitalize(fullName.replaceAll(/^prefix/, ''))
}
It works nearly the same, but uses the built-in Java class for handling the decapitalization. This method handles uppercase characters a little differently, so that prefixUPPERCASETest returns UPPERCASETest.