I am trying to do a null/empty check-in a conditional block as seen below:
However, the results are kind of bizzare in that the block with !filter.isNullOrEmpty() should not execute since the filter is null. How does isNullOrEmpty() usually work, and how and when to use it?
I just have a simple set up like:
val filter : String? = session.parameters["filter"]?.get(0).toString()
val rootJsonObject = JsonObject()
val gson = GsonBuilder().setPrettyPrinting().create()
val list = if (!filter.isNullOrEmpty()) {
NetApp.database.filmDao().getByRegionFilter(filter)
} else {
NetApp.database.filmDao().getByRandom()
}
The variable filter contains the string "null", but it's not actually null or empty. If it was null, it'd look like filter = null in the variables section, not filter = "null", note the quotes.
The reason filter contains the string "null" is that you call toString() on session.parameters["filter"]?.get(0) not in a null-safe way. get(0) returns a null value and null.toString() returns the literal string "null". To fix that, simply make it a null-safe call: session.parameters["filter"]?.get(0)?.toString()
Related
I'm trying to evaluate a string against a set list of parameters with RegExp in Flutter. For example, the string must contain at least:
One capital letter
One lowercase letter
One number from 0-9
One special character, such as $ or !
This is basically for a password entry field of an application. I have set things up, firstly using validateStructure as follows:
abstract class PasswordValidator {
bool validateStructure(String value);
}
Then, I have used the RegExp function as follows:
class PasswordValidatorSpecial implements PasswordValidator {
bool validateStructure(String value) {
String pattern =
r'^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[!##\$&*~£]).{8,}$';
RegExp regEx = new RegExp(pattern);
return regEx.hasMatch(value);
}
}
This does work well, in a sense that when I pass a string/password through it, it does tell me if at least one of the criteria is not met. However, what I would like to do is for the output to be more specific, telling me which of those criteria isn't met.
For example, if the password were to have everything but a number (from 0-9) I would want to be able to get the output to specifically say that a number is missing, but everything else is present.
How would I adapt my code to be able to do that? I thought perhaps by using conditional 'if' statement, although I don't know how that would work. Thanks!
That's right, you can use RegExr to check your RegExp, separate each part and use them separately to have a custom error. Also instead of return a bool value, you can return a String value, such as the following function:
String validateStructure(String value) {
String patternUpperCaseCharacters = r'^(?=.*?[A-Z])';
String patternLowerCaseCharacters = r'^(?=.*?[a-z])';
String patternNumbers = r'^(?=.*?[0-9])';
String patternSpecialCharacters = r'^(?=.*?[!##\$&*~£])';
RegExp regEx = new RegExp(patternUpperCaseCharacters);
if (regEx.hasMatch(value)) {
regEx = new RegExp(patternLowerCaseCharacters);
if (regEx.hasMatch(value)) {
return "More errors";
} else {
return "You need at least one lowercase letter";
}
} else {
return "You need at least one capital letter";
}
}
Update: I find that this behavior is reproducible using a simple regex such as /^[0-9]+$/. It is also reproducible using a custom validator function such as
export function textareaPattern(pattern: RegExp): ValidatorFn {
return (control: AbstractControl): {[key: string]: any} | null => {
const values = control.value.split('\n');
let mismatch = false;
values.forEach(val => {
mismatch = !pattern.test(val);
if(mismatch) {
return {textareaPattern: {value: control.value}}
}
});
return null;
}
}
Original post: I have a regex that is intended to validate that a user has entered multiple, valid IP addresses- one per line- in a text area.
/^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(/([0-9]|[1-2][0-9]|3[0-2]))?$\n?/gim
The regex works on a happy path, but gets weird once both a valid entry and an invalid entry are present.
If I enter all valid values, the form control is valid, as expected. Example:
10.1.121.2
10.2.121.3
10.3.121.4
If I enter all invalid values, the form control is not valid, as expected. Example:
butter
potato
123
If I enter a combination of valid and invalid values, the form control alternates between valid and invalid, depending on the length of the entry. If the entry's length is even, it's invalid, and odd is valid. How odd.
length: 12, Invalid
10.1.121.1
f
length: 13, Valid
10.1.121.1
fo
I'd think the problem lies in the RegEx, but I'll admit I'm far from comfortable deciphering such a behemoth of a RegEx.
The RegEx should match:
192.168.1.1
255.203.232.1
1.0.12.1
The RegEx should not match:
256.1.12.1
1934.1.22.3
201.foobar.201.1
Minimal, Reproducible Example (updated with solution): https://stackblitz.com/edit/angular-v4f35a?file=src%2Fapp%2Fapp.component.ts
So this boiled down to two issues.
The first problem was that the global flag for RegExes causes the JS engine to track a lastIndex property from which the next search will start when myRegex.test() is called again. Since the regex object is the same throughout the validation process, that lastIndex is updated and referenced as you type, and the form re-validates.
The second problem is that without global, the form would be considered valid as long as one line is correct. So my input could be
192.168.foobar
192.168.1.1
hello world!
and the form is valid because of line 2.
My Solution
I've implemented a custom validator for textareas. It accepts my regex (sans g flag) and splits the contents of the textarea on \n. It immediately assumes no mismatches, then for each line, checks that the line matches the RegEx. If not, it mismatches and returns an object containing the contents of the textarea:
import {AbstractControl, ValidatorFn} from '#angular/forms';
export function multilinePattern(pattern: RegExp): ValidatorFn {
return (control: AbstractControl): {[key: string]: any} | null => {
const values = control.value.split('\n');
if (values.length === 1 && values[0] === '') {
return null;
}
let mismatch = false;
values.forEach((val: string) => {
if (!pattern.test(val)) {
mismatch = true;
}
});
return mismatch ? {multilinePattern: {value: control.value}} : null;
};
}
I'm trying to read a ini file in a value listbox.
Example below works, but i don't know why.
ReadSectionValues contains a string list of ini lines.
How does Rad Studio parse the lines with:
ListValues->Names[i] is first part of the line and ListValues->Values[ListValues->Names[i]] is the second part?
int i;
try
{
//ShowMessage( ListBox1->Items->Strings[ListBox1->ItemIndex] );
TStringList *ListValues = new TStringList;
TIniFile* SettingsFile = new TIniFile(ExtractFilePath(Application->ExeName) + "settings.ini");
String s;
s = ListBox1->Items->Strings[ListBox1->ItemIndex];
SettingsFile->ReadSectionValues( s , ListValues);
for (i = 0; i < (ListValues->Count); i++) {
//ShowMessage(ListValues->Names[i]);
//ShowMessage(ListValues->Values[ListValues->Names[i]]);
vList1->InsertRow(ListValues->Names[i] , ListValues->Values[ListValues->Names[i]],True);
}
delete SettingsFile;
delete ListValues;
}
catch(Exception* e)
{
ShowMessage(e->Message);
}
Please explain, Rad stuido help found no explanation.
void __fastcall ReadSectionValues(
const System::UnicodeString Section,
System::Classes::TStrings* Strings
)
is a method, which gets all lines of ini-file section with name Section and stores them in TStrings-object Strings. Note that these strings have format name=value.
TStrings class has two access properties Names and Values. Their parse algorithm is very simple. If you get stringsObject->Values[1] it takes second line from stringsObject and splits it into two strings on = (or other value of NameValueSeparator property of stringsObject). The string to the left of = (separator) is returned as name (by property Name) and the string to the right of = is returned as value (by property Value).
I am trying to parse following JSON data (created with JSON.stringify). I am using libJSON 7. My code follows:
wstring jsonstr = _T("{\"Id\":0,\"Note\":\"\",\"Username\":\"user\",\"Password\":\"pass\",\"Enabled\":true,\"ProfileId\":\"\",\"UserAgent\":\"\",\"LastUsage\":0,\"Failures\":0,\"Abuses\":0}");
JSONNode jsondata = libjson::parse(jsonstr);
auto i = jsondata.begin();
auto num = i->as_float();
int idIsNan = _isnan(num);// Nonzero here
Now I expect that num == (double)0, however, it equals 1.#QNAN00000000000 instead. Does anyone know how to bypass this bug?
Also if I use as_int instead of as_float, it parses data correctly; so, it looks like this bug takes place for as_float method only.
I am guessing a bit here, since you don't show all the relevant code:
Your json structure is data, json seems to be the string you are parsing. So json.begin() would be the first character in that string, not the first json value. Since that first character is double quote, it cannot be parsed as a float -> you get the nonsense you see. Maybe this is what you want:
JSONNode data = libjson::parse(json);
auto i = data.begin(); //<-- data, not json!
auto num = i->as_float();
Please remember to give all the relevant code next time, that includes definition of all used variables (in this case, 'json').
PS: The json string you posted ends with an unmatched } - that might confuse the parser.
This is my c++ code to retrieve html data with cgi.
char* fileContentLength;
int nContentLength;
fileContentLength = getenv("CONTENT_LENGTH");
if(fileContentLength == NULL)
return -1;
nContentLength = atoi(fileContentLength);
if(nContentLength == 0)
return -1;
data = (char*) malloc(nContentLength+1);
if(data == NULL)
return -1;
memset(data, 0, nContentLength+1);
if(fread(data, 1, nContentLength, stdin) == 0)
return -1;
if(ferror(stdin))
After executing this code, i got the below result to the variable "data".
f0=fname0&l0=lname0&f1=fname1&l1=lname1&f2=fname2&l2=lname2&f3=&l3=
Here f0,l0,f1,l1 are name of the input box of the HTML page. From this string i need to separate the values like fname0, lname0,fname1,lname1 and so on. I used sscanf function. but i could not retrieve the correct result. How can i assign the values from the above string to a local variable called firstname and lastname.
Check out e.g. the strtok function. Use it in a loop to split at the '&' to get all the key-value pairs into a vector (for example). Then go though the vector splitting each string (you can use strtok again here) at the '=' character. You can put the keys and values in a std::map, or use directly.
For an even more C++-specific method, use e.g. std::string::find and std::string::substr instead of strtok. Then you can put keys and values directly into the map instead of temporary storing them as strings in a vector.
Edit: How to get the last pair
The last key-value pair is not terminated by the '&' character, so you have to check for the last pair after the loop. This can be done by having a copy of your string, and then get the substring after the last '&'. Something like this perhaps:
char *copy = strdup(data);
// Loop getting key-value pairs using `strtok`
// ...
// Find the last '&' in the string
char *last_amp_pos = strrchr(copy, '&');
if (last_amp_pos != NULL && last_amp_pos < (copy + strlen(copy)))
{
last_amp_pos++; // Increase to point to first character after the ampersand
// `last_amp_pos` now points to the last key-value pair
}
// Must be free'd since we allocated a copy above
free(copy);
The reason we need to use a copy of the string, if because strtok modifies the string.
I still would recommend to you use C++ strings instead of relying on the old C functions. It would probably simplify everything, including you not needing to add the extra check for the last key-value pair.