Regular expression which checks number of digits - regex

I have a string which contains something like this number: -7-972/516/57.15
. Expression must return the number of digits and filter by first number. In result i want to see: 79725165715
. I wrote this expression ^(\D*)+7+(\D*(?:\d\D*){10})$, but that expression got problem "Catastrophic Backtracking"(freezes on execution) with long strings like: bt.rfznascvd#rcs.ru,e.zovtrnko#lkn.ru

I write a new one and that works: \D*7(\d\D*){10}

You just have to use \d. Using of Matches will give you all matches in pattern from considered line. Count of it wwill give you count of matches. And for concatanate them to string I created small extension method.
For testing your regexes I can advice regexlib.
namespace CSharpTest
{
using System.Text;
using System.Text.RegularExpressions;
public static class Program
{
static void Main(string[] args)
{
string input = #"number: -7-972/516/57.15";
var regex = new Regex(#"\d");
var matches = regex.Matches(input);
var countOfNumbers = matches.Count;
var number = matches.ToNumber();
}
public static string ToNumber(this MatchCollection matches)
{
var result = new StringBuilder();
foreach (Match match in matches)
result.Append(match.Value);
return result.ToString();
}
}
}

Related

Need help for RegExp (in Flutter)

I'm trying to filter a String list like:
List<String> names = ["NAM", "XYZ", "+QWE (HJB)", "+XYZ (NAM)", "(NAM)"];
While using regex I want to compare each String with a string that contains "NAM" or "HJB" and print every string of names containing the filter string out. So in the end it would print out everything with "NAM" in it (also "+XYZ (NAM)", but without the special chars)
My code looks like this but either way I catch everything ("+QWE (HJB)")
regexp3 = RegExp(r'[a-zA-Z]+');
or Nothing
final regexp2 = RegExp(r'^\+.([a-zA-Z]+) \(([a-zA-Z]+).\).$');
because if I only filter with "NAM" (for example) it gives me an null error.
Complete code.
void main() async {
List<String> names= ["TEX","TOL","+TEX (TOL)","+TOL (TEX)", "(NAM)"];
List<String> filter = ["TEX", "TOL"];
final regexp3 = RegExp(r'[a-zA-Z]+');
for(var e in names){
if(filter.contains(regexp3.firstMatch(e)!.group(0))) {
print(e);
}
}
}
Writing regex patterns is indeed giving us a slight nystagmus. However, it is important to be careful about the regex groups numeration. As far as I understand, you want to get the content of group(1) which is captured by the first parenthesis after \+.
To match the strings correctly I also removed a few . characters from the regex pattern.
Replaced the bang operator (!) with ? and ?? in addition to provide safe default value instead of throwing errors on nulls.
Good luck!
void main() async {
List<String> names= ["TEX","TOL","+TEX (TOL)","+TOL (TEX)", "(NAM)"];
List<String> filter = ["TEX", "TOL"];
final regexp3 = RegExp(r'^\+([a-zA-Z]+) \(([a-zA-Z]+)\)$');
for(var e in names){
var regroup = regexp3.firstMatch(e)?.group(1);
if(filter.contains(regroup)) {
print(e + '\t\t' + (regroup ?? ''));
}
}
}

regex keeps returning false even when regex101 returns match

I am doing a list.where filter:
String needleTemp = '';
final String hayStack =
[itemCode, itemDesc, itemCodeAlt, itemDescAlt, itemGroup].join(' ');
for (final k in query.split(" ")) {
needleTemp = '$needleTemp(?=.*\\Q$k\\E)';
}
var re = RegExp(needleTemp);
return re.hasMatch(hayStack);
I printed the output for needleTemp and it looks the same as on my regex101 example:
in dart it prints (?=.*\Qa/a\E)(?=.*\Qpatro\E)
basically the same, but nothing matches, not even a simple letter.
Is dart regex different or do I need another syntax?
edit:
Simple example to test in DartPad:
void main() {
print("(?=.*\\Qpatrol\\E)");
var re = RegExp("(?=.*\\Q2020\\E)");
print(re.hasMatch('A/A PATROL 2020'));
}
still returns false
Found the solution:
I just need to remove \Q and \E then RegExp.escape(text_to_escape) inside the needle.

Extract value within brackets using regex

Below code works fine, and gives the value within brackets (but i want it to return value WITHOUT bracket, output gives me the value but with bracket)
string regularExpressionPattern = #"\[(.*?)\]";
string inputText = "Find string inside brackets [C#.net] and [Vb.net] example.";
Regex re = new Regex(regularExpressionPattern);
foreach (Match m in re.Matches(inputText))
{
Console.WriteLine(m.Value);
}
Console.ReadLine();
}
Output:
[C#.net]
[Vb.net]
[ASP.net]
Output Expected:
C#.net
Vb.net
ASP.net
Use m.Groups[1].Value to get the desired values in the foreach loop:
void Main()
{
string regularExpressionPattern = #"\[(.*?)\]";
string inputText = "Find string inside brackets [C#.net] and [Vb.net] example.";
Regex re = new Regex(regularExpressionPattern);
foreach (Match m in re.Matches(inputText))
{
Console.WriteLine(m.Groups[1].Value);
}
}
instead of m.Value, use whatever method is used by your undisclosed language to get 1st group, e.g. in C#.NET:
m.Groups[1]

Regular expression to match all digits of unknown length except the last 4 digits

There is a number with unknown length and the idea is to build a regular expression which matches all digits except last 4 digits.
I have tried a lot to achieve this but no luck yet.
Currently I have this regex: "^(\d*)\d{0}\d{0}\d{0}\d{0}.*$"
Input: 123456789089775
Expected output: XXXXXXXXXXX9775
which I am using as follows(and this doesn't work):
String accountNumber ="123456789089775";
String pattern = "^(\\d*)\\d{1}\\d{1}\\d{1}\\d{1}.*$";
String result = accountNumber.replaceAll(pattern, "X");
Please suggest how I should approach this problem or give me the solution.
In this case my whole point is to negate the regex : "\d{4}$"
You may use
\G\d(?=\d{4,}$)
See the regex demo.
Details
\G - start of string or end of the previous match
\d - a digit
(?=\d{4,}$) - a positive lookahead that requires 4 or more digits up to the end of the string immediately to the right of the current location.
Java demo:
String accountNumber ="123456789089775";
String pattern = "\\G\\d(?=\\d{4,}$)"; // Or \\G.(?=.{4,}$)
String result = accountNumber.replaceAll(pattern, "X");
System.out.println(result); // => XXXXXXXXXXX9775
still not allowed to comment as I don't have that "50 rep" yet but DDeMartini's answer would swallow prefixed non-number-accounts as "^(.*)" would match stuff like abcdef1234 as well - stick to your \d-syntax
"^(\\d+)(\\d{4}$)"
seems to work fine and demands numbers (minimum length 6 chars). Tested it like
public class AccountNumberPadder {
private static final Pattern LAST_FOUR_DIGITS = Pattern.compile("^(\\d+)(\\d{4})");
public static void main(String[] args) {
String[] accountNumbers = new String[] { "123456789089775", "999775", "1234567890897" };
for (String accountNumber : accountNumbers) {
Matcher m = LAST_FOUR_DIGITS.matcher(accountNumber);
if (m.find()) {
System.out.println(paddIt(accountNumber, m));
} else {
throw new RuntimeException(String.format("Whooaaa - don't work for %s", accountNumber));
}
}
}
public static String paddIt(String input, Matcher m) {
StringBuilder b = new StringBuilder();
for (int i = 0; i < m.group(1).length(); i++) {
b.append("X");
}
return input.replace(m.group(1), b.toString());
}
}
Try:
String pattern = "^(.*)[0-9]{4}$";
Addendum after comment: A refactor to only match full numerics could look like this:
String pattern = "^([0-9]+)[0-9]{4}$";

Accessing capture groups in AS3 RegEx

I have a document that looks like this:
public class FunctionalColors {
private static var colorArray:Array = new Array();
public function FunctionalColors(e:Enforcer) {
}
public static function get colors():Array {
if (colorArray.length == 0) {
colorArray["DIRECT CABLING"] = 0x61568F;
colorArray["10Base2 ETHERNET"] = 0x37699B;
colorArray["10BaseT ETHERNET"] = 0x6699FF;
colorArray["1 Gb Ethernet"] = 0x4169FF;
colorArray["10 Gb Ethernet"] = 0x00CDD0;
}
return colorArray;
}
}
I need to pull out the keys of the colorArray (i.e. "Direct Cabling", "10Base2 Ethernet", etc.) and store them in another array. I have a regular expression that looks like this
var colorsRegEx:RegExp = new RegExp(/colorArray\[\"(.*)\"\]/g);
This matches the entirety of, for example, "colorArray["DIRECT CABLING"]." Is there a way to grab just the (.*) capture group so I just have the dictionary key? It looks like if you're using the String.replace method, you can target particular capture groups, but I'm not seeing a way to pull them out to use them elsewhere. Thanks.
I'd advise to use lazy matching .*? in the pattern in order not to overmatch (*? quantifier is called lazy and will only match as few occurrences of the quantified subpattern as possible), and to grab all the occurrences of captured values, you may use a while loop inside which will call the re.exec until no match:
var pattern:RegExp = /colorArray\["(.*?)"]/g;
var str:String = "<<YOUR_STRING_HERE>>";
var result:Array = [];
var m:Array = pattern.exec(str);
while (m != null)
{
result.push(m[1]);
m = pattern.exec(str);
}
Note also that you do not have to use a RegExp constructor notation when using a static regex pattern (i.e. using no variables to build it), use the simple /.../ regex literal notation.