Implementing Pattern with RegExp in Dart - regex

I wanted to have a Pattern where I could easily get the base path of the pattern, for use with routing, like this:
var route = new Pattern('/user');
print(route.path)
would give '/user', but the pattern would match r'/user/.*'.
I pictured this would suffice:
class Path extends RegExp {
String _path;
Path(this._path): super(path.join(_path, '.*'));
}
However, RegExp is abstract, so it cannot work. But RegExp is still instantiable because it's constructor is declared with factory. Therefore, I find the only / best solution is to keep a RegExp object as a member:
class Path implements Pattern {
String _path;
RegExp _r;
Path(this._path) {
_r = new RegExp(join(_path, '.*'));
}
Match matchAsPrefix(String string, [int start=0]) {
return _r.matchAsPrefix(string, start);
}
Iterable<Match> allMatches(String str) {
return _r.allMatches(str);
}
}
But the definition of RegExp lists only allMatches, as specified by Pattern. But doesn't all of Patterns method need to be implemented if RegExp is to support Pattern?
I wanted to look at the implementation of RegExp's constructor, but it's defined as external, and I can't find the correct file.
So properly formulate my question, is there any way for me to do what I originally intended, to inherit from a non-abstract class implementing Pattern?

I would recommend that you look at the Uri class or Path package, and see if it can't help you with what you want (and if it can't, file a feature request). Working with paths or URIs as strings is likely to be fragile.
Anyway, if I understand you correctly, you want the input x to be match "$x/" and everything after that. That sounds fairly simple - since it matches to the end of the string, there can only ever be one match per string.
You can write your own Pattern implementation:
class MyPattern implements Pattern {
final String _pattern;
MyPattern(String prefix) : _pattern = "$prefix/";
Iterable<Match> allMatches(String input) {
int index = input.indexOf(_pattern);
if (index < 0) return null;
return [new _MyMatch(input, this, index)];
}
Match matchAsPrefix(String input, [int start = 0]) {
if (input.startsWith(_pattern, start)) {
return new _MyMatch(input, this, start);
}
return null;
}
}
class _MyMatch implements Match {
final String input;
final Pattern pattern;
final int start;
_MyMatch(this.input, this.pattern, this.start);
int get end => input.length;
int get groupCount => 0;
List<String> groups(Iterable<int> indices) {
var result = <String>[];
for (int i in indices) result.add(group(i));
return result;
}
String group(int index) {
if (index == 0) return input.substring(start);
throw new RangeError.value(index);
}
String operator[](int index) => group(index);
}

I think it is fine how you did it (RegExp as member).
The abstract class with the factory constructor is a construct to prevent deriving from RegExp.
The external keyword is a trick to bind to a concrete implementation from somewhere else later (VM or JS, see https://www.dartlang.org/docs/spec/latest/dart-language-specification.html#h.lkkt75qhbiwh).
This is the reason why the abstract class can be instantiated and why RegExp doesn't have to implement all methods in the regexp.dart file.

Related

Regex-validated strings in Typescript: an implementation

Regex-validated strings are not a thing in Typescript.
Still, the need is here: in my case, immutable strings that are validated against a Regex for UUIDv4, URIs, Email, etc.
I've got something close but I'm not happy with it, I have to rewrite the regex access and test function every time.
Here's what I have so far:
An abstract class "ValidatedString"
export interface Predicate<T> { (x: T): boolean }
export abstract class ValidatedString {
#str: string
constructor(str: string, predicate: Predicate<string>, className?: string) {
if (!predicate(str)) throw new Error(`Invalid ${className ? className : 'format'}: ${str}`)
this.#str = str
}
get length() { return this.#str.length }
toString = () => this.#str
}
And classes that implement it:
import { v4 } from 'uuid'
/** Regex-validated string class for UUIDv4 */
export class UUIDv4 extends ValidatedString {
constructor(str: string) { super(str, UUIDv4.test, 'UUID v4') }
static readonly regex = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i
/** Test if a string matches the class predicate */
static test = (str: string) => UUIDv4.regex.test(str)
/** Generate a random string that matches the class predicate */
static generate = () => new UUIDv4(v4())
}
/** Regex-validated string class for UUIDv4 */
export class ApiVersion extends ValidatedString {
constructor(str: string) { super(str, ApiVersion.test, 'API version') }
static readonly regex = /^[0-9]+\.[0-9]+(\.[0-9]+)?[a-z]*$/
/** Test if a string matches the class predicate */
static test = (str: string) => ApiVersion.regex.test(str)
}
Despite my efforts to eliminate the obvious redundancies between the inheriting classes, I have failed: one cannot use a protected static field in the abstract class, so I'm left with rewriting the test function and the regex access every time.
I can't offer a generic signature for the generate function either.
I would like to basically build UUIDv4 as a ValidatedString with UUIDv4 regex and offer a regex access,test method and optional generate function signature.
Do you see how to implement this properly? Is there a way to build a type from a static parameter such as a Regex literal?

regular expression matches all string(include space) without kind of specific string contain

I'm trying to match a class in my Java source code, for example:
public class PersonMeta {
private long id;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
}
public class PersonMeta2 {
}
For this code I should get to different classes in my result collection, PersonMeta and PersonMeta2.
//result0
public class PersonMeta {
...
}
//result1
public class PersonMeta2 {
}
So I tried this expression:
(public\s)?class\s\w+\s*{[\s\S]*}
But obviously it's incorect, it will meatch the whole file, so I tried to use ?, but it's not what I want either, it will give me this:
public class PersonMeta {
private long id;
public long getId() {
return id;
}
So I think I need to write an expression like this:
(public\s)?class\s\w+\s*{_ThePatent_}
_ThePatent_ should means that : any string or space but not include this patent(I know that it's not very strict, a string variable can also contain it, but please ignore it at first):
(public\s)?class\s\w+\s*{
I have read some question, and I tried to use like:
//Match every string without "abc"
(public\s)?class\s\w+\s*{((?!abc).)*}
It should work because there is no "abc" in my class, but it shouldn't, and I don't think it can match the space so I tried to optimize it to:
(public\s)?class\s\w+\s*{((?!abc)[\s\S])*}
But it gives to me the whole file.
So the question is how can I get what I want?
If all your classes are that simple with just attributes and default getters and setters, you can make sure that all the braces are balanced by having every opening brace after the class declaration be followed by a closing brace and then match the next closing brace as the end of the class. If you have nested braces, you could look into how recursive regexes work in Java.
(?:public\s)?class\s(\w+)\s*{(?:[^{}]|{[^}]*})*}
This will work on your example and save the class name in the first match group.
By the way, if you just want to match any character you can use . instead of [\s\S].

Regex as associative array key?

I'm working on a very performance dependent portion of my code in D. For this, I want to have an associative array mapping my data to a Regex so that I can use it later.
When I try to do this, it gives me the error, index is not a type or expression. How can I use this regex as my array key?
Edit: For code, here's what I'm trying to define in my class:
View[Regex] m_routes;
I want that so that I can add the routes like below:
void add(string route, View view)
{
auto regex = regex(route.key, [ 'g', 'i' ]);
if (regex in m_routes)
throw new Exception(format(`Route with path, "%s", is already assigned!`, route));
m_routes[regex] = view;
}
This would then allow me to check the regex against a route, without having to rebuild each one, shown in this method:
View check(string resource)
{
foreach (route; m_routes.byKeyValue())
{
auto match = matchAll(resource, route.key);
// If this regex is a match
// return the view
if (!match.empty)
{
return route.value;
}
}
return null;
}
Any help would be appreciated, thank you!
It seems std.regex.Regex is an alias that takes a type parameter:
(from std.regex.package, line 289 in release 2.071.0)
public alias Regex(Char) = std.regex.internal.ir.Regex!(Char);
In other words, you'll need to specify the char type for the regex. For string, that'd be char:
View[Regex!char] m_routes;

What type should my variable be declared as?

I am new to C# / OOP and am working on converting an existing application into .net 4.0 framework.
My code is as follows:
Class abc
private IList<string[]> GetReportBatchList()
{
List<string[]> rowList = new List<string[]>();
SqlParameter[] prm = { new SqlParameter("#rpt_doc_type_id", SqlDbType.Int, 9) };
prm[0].Value = 101;
try
{
.....
.....
.....
}
return rowList;
}
class xyz
using abc;
Private Function GenerateReport()
Try
{
Dim rptBatchList As ??????
rptBatchList = GetReportBatchList()
While rptBatchList.Read()
......
......
......
}
catch
{
......
}
What type should rptBatchList be declared as?
Since the return value of GetReportBatchList() has IList of string as its type, it makes sense that rptBatchList should be the same type.
Your second example is VB, but you say you are using C#, so...
For C# it would be IList<string[]>.
My VB is a little rusty, but I think it would be IList(Of String()).
Hmmm... is this a question about correct return types, or a question about translating C# into VB.Net?
According to the function definition you have, rptBatchList will be of type IList<string[]> - obviously declared in the correct syntax for VB.Net.
Further to that, because it is a list of string arrays, it doesn't have a Read() function, so maybe you were looking for something that derives from DbDataReader instead (like a SqlDataReader)? If you do intend to stick with the current definition then you can use either a foreach or a for loop to iterate over the list elements, or you can use Linq extensions and use something like this:
rptBatchList.ForEach(z => { z.ForEach(x => doSomethingWithThisResultString(x)); } );
although that can get messy fast - you probably want to just stick with a couple of nested foreach loops.

RegExpValidator never matches

I've got a class that's meant to validate input fields to make sure the value is always a decimal. I've tested the regex here: http://livedocs.adobe.com/flex/3/html/help.html?content=validators_7.html, and it looks like it does the right thing, but in my app, I can't seem to get it to match to a number format.
Class Definition:
public class DecimalValidator {
//------------------------------- ATTRIBUTES
public var isDecimalValidator:RegExpValidator;
//------------------------------- CONSTRUCTORS
public function DecimalValidator() {
isDecimalValidator = new RegExpValidator();
isDecimalValidator.expression = "^-?(\d+\.\d*|\.\d+)$";
isDecimalValidator.flags = "g";
isDecimalValidator.required = true;
isDecimalValidator.property = "text";
isDecimalValidator.triggerEvent = FocusEvent.FOCUS_OUT;
isDecimalValidator.noMatchError = "Float Expected";
}
}
Setting the source here:
public function registerDecimalInputValidator(inputBox:TextInput, valArr:Array):void {
// Add Validators
var dValidator:DecimalValidator = new DecimalValidator();
dValidator.isDecimalValidator.source = inputBox;
dValidator.isDecimalValidator.trigger = inputBox;
inputBox.restrict = "[0-9].\\.\\-";
inputBox.maxChars = 10;
valArr.push(dValidator.isDecimalValidator);
}
And Calling it here:
registerDecimalInputValidator(textInput, validatorArr);
Where textInput is an input box created earlier.
Clearly I'm missing something simple yet important, but I'm not entirely sure what! Any help would be much appreciated.
I don't know ActionScript, but as far as I know it's an ECMAScript language, so I expect you need to escape the backslashes if you use a string to define a regex:
isDecimalValidator.expression = "^-?(\\d+\\.\\d*|\\.\\d+)$";
This strikes me as wrong; but I can't quite put my finger on it. For your DecimalValidator instead of composing a RegExpValidator; why not extend it?
public class DecimalValidator extend RegExpValidator{
//------------------------------- CONSTRUCTORS
public function DecimalValidator() {
super()
this.expression = "^-?(\d+\.\d*|\.\d+)$";
this.flags = "g";
this.required = true;
this.property = "text";
this.triggerEvent = FocusEvent.FOCUS_OUT;
this.noMatchError = "Float Expected";
}
}
How when is the registerdecimalInputValidator called? I have a slight worry about the Validator instance is a local variable to a method instead of 'global' property to the function.
protected var dValidator:DecimalValidator = new DecimalValidator();
public function registerDecimalInputValidator(inputBox:TextInput):void {
dValidator.isDecimalValidator.source = inputBox;
dValidator.isDecimalValidator.trigger = inputBox;
}
I'm not sure why you are setting restrictions on the TextInput in the registerDecimalInputValidator method; that should be done when you create the method (in createChildren() or possibly in response to public properties changing, in commitProperties . It is also not obvious to me what the validatorArr does. If you're expecting to access values inside the validatorArrray outside of the method; it would often be a common practice to return that value from the method. Without looking it up; I'm not sure if Arrays are passed by value or reference in Flex.