Regex get group n from group results - regex

I have a result from a database query that is:
IEnumerable<ResultRecord> results_from_db_call = Db.GoGetItNow();
Now lets assume the returned class looks like:
public class ResultsRecord
{
public string DataBlob { get; set; }
public int FirstID { get; set; }
public int SecondNum { get; set; }
public DateTime ThirdDate { get; set; }
public string FourthTime { get; set; }
public string FifthTime { get; set; }
}
Now, the result records returned only have the DataBlob member set
It very well might look like:
<IK/12322>1354654 16/MAY/2014 18:01:01 - 20:01:01
So, I need to fill the other members, and would like to do so with an 'Each' delegate:
results.Each(f => f.FirstID = int.Parse(Regex.Match(f.DataBlob, #"\d+").Value));
results.Each(f => f.SecondNum = int.Parse(Regex.Match(f.DataBlob, #"\d+").Value));
results.Each(f => f.ThirdDate = DateTime.Parse(Regex.Match(f.DataBlob, #"\d+").Value));
results.Each(f => f.FourthTime = Regex.Match(f.DataBlob, #"\d+").Value));
results.Each(f => f.FifthTime = Regex.Match(f.DataBlob, #"\d+").Value));
Well, as you can imagine, that regex expression only worked on the first integer..
But wait! I have a working Regex to find all the groups I need:
(\d+)\>(\d+) (\d+\/[a-zA-Z]+\/\d+) (\d+\:\d+\:\d+) - (\d+\:\d+\:\d+)
This successfully groups all items that I need.
But, and here's the question, how do I get the second regex group item for SecondNum, the third regex group item for ThirdDate, the fourth regex group item for FourthTime, and the fifth regex group item for FifthTime?
When I try
(\d+)\>(\d+) (\d+\/[a-zA-Z]+\/\d+) (\d+\:\d+\:\d+) - (\d+\:\d+\:\d+){0}
I don't get the first (zeroth) item.
How can I call the regex to get the first, etc item from the groupings?
results.Each(f => f.SecondNum = int.Parse(Regex.Match(f.DataBlob, #"????").Value));

You should parse the whole string first so that you will be able to capture different groups:
string pattern = #"(\d+)\>(\d+) (\d+\/[a-zA-Z]+\/\d+) (\d+\:\d+\:\d+) - (\d+\:\d+\:\d+)";
Match m = Regex.Match(f.DataBlob, pattern);
// You can then refer to the matched group this way:
// m.Groups[1] = 12322
// m.Groups[2] = 1354654
// ...etc
Group g = m.Groups[2];
// Then parse into integer
Do note that capture group starts from 1, instead of 0. You can also take a look at the example here.

Related

JavaFX - TextField with regex for zipcode

for my programm I want to use a TextField where the user can enter a zipcode (German ones). For that I tried what you can see below. If the user enters more than 5 digits every additional digit shall be deleted immediately. Of course letters are not allowed.
When I use this pattern ^[0-9]{0,5}$ on https://regex101.com/ it does what I intended to, but when I try this in JavaFX it doesn't work. But I couldn't find a solution yet.
Can anyone tell me what I did wrong?
Edit: For people, who didn't work with JavaFX yet: When the user enters just one character, the method check(String text) is called. So the result should also be true, when there are 1 to 5 digits. But not more ;-)
public class NumberTextField extends TextField{
ErrorLabel label;
NumberTextField(String text, ErrorLabel label){
setText(text);
setFont(Font.font("Calibri", 17));
setMinHeight(35);
setMinWidth(200);
setMaxWidth(200);
this.label = label;
}
NumberTextField(){}
#Override
public void replaceText(int start, int end, String text){
if(check(text)) {
super.replaceText(start, end, text);
}
}
#Override
public void replaceSelection(String text){
if(check(text)){
super.replaceSelection(text);
}
}
private boolean check(String text){
if(text.matches("^[0-9]{0,5}$")){
label.setText("Success");
label.setBlack();
return true;
} else{
return false;
}
}
You don't need to extend TextField to do this. In fact I recommend using a TextFormatter, since this is simpler to implement:
It does not require you to overwrite multiple method. You simply need to decide based on the data about the desired input, if you want to allow the change or not.
final Pattern pattern = Pattern.compile("\\d{0,5}");
TextFormatter<?> formatter = new TextFormatter<>(change -> {
if (pattern.matcher(change.getControlNewText()).matches()) {
// todo: remove error message/markup
return change; // allow this change to happen
} else {
// todo: add error message/markup
return null; // prevent change
}
});
TextField textField = new TextField();
textField.setTextFormatter(formatter);
Your original expression should be working fine, if we wish to validate a five-digits zip though, we might want to drop the 0 quantifier:
^[0-9]{5}$
^\d{5}$
For validation purposes, we might want to keep the start and end anchors, however for just testing, we can remove and see:
[0-9]{5}
\d{5}
It is likely that some other chars, would get through our inputs, which we do not wish to have.
Demo
Test
import java.util.regex.Matcher;
import java.util.regex.Pattern;
final String regex = "^[0-9]{5}$";
final String string = "01234\n"
+ "012345\n"
+ "0\n"
+ "1234";
final Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE);
final Matcher matcher = pattern.matcher(string);
while (matcher.find()) {
System.out.println("Full match: " + matcher.group(0));
for (int i = 1; i <= matcher.groupCount(); i++) {
System.out.println("Group " + i + ": " + matcher.group(i));
}
}

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))
}

Value of Mobile Number entered showing "not a valid number" despite putting in regex for 10 digits

I am trying to put in validation for the mobile number entered by the user despite putting in regular expression for 10 digit mobile number.
Here is the Model class
public partial class student1
{
public int StudentId { get; set; }
[Required]
[StringLength(30)]
public string Name { get; set; }
public string Branch { get; set; }
[Display(Name = "Mobile Number:")]
[Required(ErrorMessage = "Mobile Number is required.")]
[RegularExpression("^([07][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9] | 8[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9] | 9[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9])", ErrorMessage = "Invalid Mobile Number.")]
public Nullable<int> Mobile { get; set; }
}
Create view
#Html.EditorFor(model => model.Mobile)
#Html.ValidationMessageFor(model => model.Mobile, "", new { #class = "text-danger" })
When I run it, for mobile number entered less than 10 it shows the error message that I had written. But for value 10 and greater I get a new message that says
The value '999999999' is not valid for Mobile Number:.
I don't know where is this message coming from. Also, why isn't it accepting the 10 digit value?
Maximum value for int in c# for 64 bit machine is
2,147,483,647
which is less than 9999999999 so it is overflow for int, so it is error message for model validation from Controller before model binding.
Convert int to long
public Nullable<long> Mobile { get; set; }
Also check regular expression, it might miss some valid numbers too.
int max value for c# source:
https://msdn.microsoft.com/en-us/library/system.int32.maxvalue(v=vs.110).aspx
What is the int.MaxValue on a 64-bit PC?
try Regular Expression = ^(\d{1,3}[- ]?)?\d{10}$

Using Regex Formatter To Verify Email

This is my code but it doesn't work,why?I use the RegexFormatter("#.*") but it seems doesn't work.it can't check the JFormattedTextField whether #.* contain or not.And I want to show the result at the verify label how should I do?
public class hw5 extends JFrame {
private JPanel contentPane;
private JPasswordField passwordField;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
hw5 frame = new hw5();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public hw5() {
setTitle("hw5");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JFormattedTextField FormattedField = new JFormattedTextField(new RegexFormatter("*#*.*"));
}
}
class RegexFormatter extends DefaultFormatter {
private Pattern pattern;
private Matcher matcher;
public RegexFormatter() {
super();
}
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;
}
}
Your regex *#*.* if wrong. It means:
One *
Followed by zero or more #
Followed by zero or more characters (any)
Validating an e-mail via regex is very complicated (if you want to do it correctly). Since it seems all you want to do is check for "something with an #", I'd suggest the following regex:
[^#]+#[^#]+
Or better yet:
^[^#]+#.[^#]+$
It means:
^: start of string
[^#]+: followed by one or more characters that are not #
#: a single #
[^#]+: followed by one or more characters that are not #
$
This will match a#b and alpha+beta$#^& but will fail on foo or a#b#c. Whether this is sufficient for you, I don't know. There are far better ways to validate whether an input is an e-mail address.

PETAPOCO - Invalid object name

I am using CTE with PetaPOCO and getting a strange error
SQL Exception: Invalid Object Name PayTransactionForRollingVacationAverage that references the model that the data should map to.
The code is as follows.
public IEnumerable<PayTransactionForRollingVacationAverage> GetPayTransactionForRollingVacationAverage(DateTime payEndingDate)
{
PointsNorth.PetaPoco.Sql sql = new PointsNorth.PetaPoco.Sql();
sql.Append(#"
;with HolidayWeeks as
(
Select Distinct EmployeeId, PayEndDate, 'Y' as HolidayWeek
from PayTransactions
where PayEndDate = #payEndingDate
and LaborCode in ('251', '249')
)", new { payEndingDate });
sql.Append(#"
Select
PT.EmployeeId,
PT.PayEndDate,
J.JobClass,
PayCodes.AverageRateCode,
PT.RegularHours,
PT.RegularRate,
PT.RegularAmount
from PayTransactions PT
Left Outer Join PayCodes on PayCodes.PayCodeCode = PT.LaborCode
Left Outer Join HolidayWeeks as H on H.PayEndDate = PT.PayEndDate and H.EmployeeId = PT.EmployeeId
Inner Join Jobs as J on J.JobId = PT.JobId
where PT.PayEndDate = #payEndingDate
and IsNull(H.HolidayWeek, 'N') <> 'Y'
order by PT.EmployeeId, PT.PayEndDate, J.JobClass", new { payEndingDate });
var data = Database.Query<PayTransactionForRollingVacationAverage>(sql);
return data;
}
The model is pretty simple:
public class PayTransactionForRollingVacationAverage
{
public long EmployeeId { get; set; }
public DateTime PayEndDate { get; set; }
public string JobClass { get; set; }
public string AverageRateCode { get; set; }
public decimal RegularHours { get; set; }
public decimal RegularRate { get; set; }
public decimal RegularAmount { get; set; }
}
I tried breaking the SQL up to make sure it was building correctly, but I still get the error. Any idea why this is occurring?
Remove the whitespace before the semi-colon.
According to Alex Jorgenson's link, this is fixed if you make a semi-colon the very first character.
According to my testing, this is strictly the first character, i.e. if there is even some whitespace before the semi-colon, the auto-generated code will still be spit out.
This is a known issue with Peta Poco. It appears to be fixed in some version but I don't know which one. You can find more information and a work around for this particular issue at https://github.com/toptensoftware/PetaPoco/issues/22