What regular expression can I use to match a cell reference? - regex

For one of my projects I want to use a regular expression to match a string like "REF:Sheet1!$C$6".
So far I have done
public static private bool IsCellReference()
{
string CELL_REFERENCE_PATTERN = #"REF:Sheet[1-9]!$[A-Z]$[0-9]";
Regex r = new Regex(CELL_REFERENCE_PATTERN);
Match m = r.Match("REF:Sheet1!$C$6");
if (m.Success) return true;
else return false;
}
but it is not working. It is returning false.
Where am I wrong?

You need to escape your $ signs.
REF:Sheet[1-9]!\$[A-Z]\$[0-9]
See Regular Expression Language Elements for more information
Also, this page is good for testing your regexes: A better .NET Regular Expression Tester

Related

Match longest substring with regex [duplicate]

I tried looking for an answer to this question but just couldn't finding anything and I hope that there's an easy solution for this. I have and using the following code in C#,
String pattern = ("(hello|hello world)");
Regex regex = new Regex(pattern, RegexOptions.IgnoreCase);
var matches = regex.Matches("hello world");
Question is, is there a way for the matches method to return the longest pattern first? In this case, I want to get "hello world" as my match as opposed to just "hello". This is just an example but my pattern list consist of decent amount of words in it.
If you already know the lengths of the words beforehand, then put the longest first. For example:
String pattern = ("(hello world|hello)");
The longest will be matched first. If you don't know the lengths beforehand, this isn't possible.
An alternative approach would be to store all the matches in an array/hash/list and pick the longest one manually, using the language's built-in functions.
Regular expressions (will try) to match patterns from left to right. If you want to make sure you get the longest possible match first, you'll need to change the order of your patterns. The leftmost pattern is tried first. If a match is found against that pattern, the regular expression engine will attempt to match the rest of the pattern against the rest of the string; the next pattern will be tried only if no match can be found.
String pattern = ("(hello world|hello wor|hello)");
Make two different regex matches. The first will match your longer option, and if that does not work, the second will match your shorter option.
string input = "hello world";
string patternFull = "hello world";
Regex regexFull = new Regex(patternFull, RegexOptions.IgnoreCase);
var matches = regexFull.Matches(input);
if (matches.Count == 0)
{
string patternShort = "hello";
Regex regexShort = new Regex(patternShort, RegexOptions.IgnoreCase);
matches = regexShort.Matches(input);
}
At the end, matches will be be the output of "full" or "short", but "full" will be checked first and will short-circuit if it is true.
You can wrap the logic in a function if you plan on calling it many times. This is something I came up with (but there are plenty of other ways you can do this).
public bool HasRegexMatchInOrder(string input, params string[] patterns)
{
foreach (var pattern in patterns)
{
Regex regex = new Regex(pattern, RegexOptions.IgnoreCase);
if (regex.IsMatch(input))
{
return true;
}
}
return false;
}
string input = "hello world";
bool hasAMatch = HasRegexMatchInOrder(input, "hello world", "hello", ...);

Regular expression checking URLs, only allowing lowercase [duplicate]

What is the regular expression (in JavaScript if it matters) to only match if the text is an exact match? That is, there should be no extra characters at other end of the string.
For example, if I'm trying to match for abc, then 1abc1, 1abc, and abc1 would not match.
Use the start and end delimiters: ^abc$
It depends. You could
string.match(/^abc$/)
But that would not match the following string: 'the first 3 letters of the alphabet are abc. not abc123'
I think you would want to use \b (word boundaries):
var str = 'the first 3 letters of the alphabet are abc. not abc123';
var pat = /\b(abc)\b/g;
console.log(str.match(pat));
Live example: http://jsfiddle.net/uu5VJ/
If the former solution works for you, I would advise against using it.
That means you may have something like the following:
var strs = ['abc', 'abc1', 'abc2']
for (var i = 0; i < strs.length; i++) {
if (strs[i] == 'abc') {
//do something
}
else {
//do something else
}
}
While you could use
if (str[i].match(/^abc$/g)) {
//do something
}
It would be considerably more resource-intensive. For me, a general rule of thumb is for a simple string comparison use a conditional expression, for a more dynamic pattern use a regular expression.
More on JavaScript regexes: https://developer.mozilla.org/en/JavaScript/Guide/Regular_Expressions
"^" For the begining of the line "$" for the end of it. Eg.:
var re = /^abc$/;
Would match "abc" but not "1abc" or "abc1". You can learn more at https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions

Regex to match all occurrences that begin with n characters in sequence

I'm not sure if it's even possible for a regular expression to do this. Let's say I have a list of the following strings:
ATJFH
ABHCNEK
BKDFJEE
NCK
ABH
ABHCNE
KDJEWRT
ABHCN
EGTI
And I want to match all strings that begin with any number of characters for the following string: ABHCNEK
The matches would be:
ABH
ABHCN
ABHCNE
ABHCNEK
I tried things like ^[A][B][H][C][N][E][K] and ^A[B[H[C[N[E[K]]]]]], but I can't seem to get it to work...
Can this be done in regex? If so, what would it be?
The simplest can be
^(?:ABHCNEK|ABHCNE|ABHCN|ABHC|ABH|AB|A)$
See demo.
https://regex101.com/r/eB8xU8/6
Use this regular expression:
^[ABHCNEK]+$
You haven't said how you want to use it, but one option doesn't require regex. Loop through the various strings and check for a match within your test string:
var strings = ['ATJFH', 'ABHCNEK', 'BKDFJEE', 'NCK', 'ABH', 'ABHCNE', 'KDJEWRT', 'ABHCN', 'EGTI'];
var test = 'ABHCNEK';
for (var i = 0; i < strings.length; i++) {
if (test.match(strings[i])) {
console.log(strings[i]);
}
}
This returns:
ABHCNEK
ABH
ABHCNE
ABHCN

Regular Expression to mask given number either from begining or end

I have a scenario where have to mask two number in return from my application based on the configured regular expression patterns. I have following two numbers and need to mask as shown below.
20128569 --> 2012****
40953186 --> ****3186
I need two regular expression patterns to achieve this pattern accordingly using the String.replaceAll(...) or some other possible way.
public static void main(String[] args) {
String value = "20128569";
String pattern = "(?<=.{4}).?" ;
String formattedValue = value.replaceAll(pattern, "*");
System.out.println(formattedValue);
}
Note: I need two regular expression patterns in order to mask number as shown above.
However currently i have resolve this issue temporally through the following code. But it is nice if i can resolve this issue through only regular expression.
String maskedAccountNumber = Pattern.compile(aRegexPattern).matcher(aKey).replaceFirst(MASK_CHARACTER);
StringBuilder maskBuffer = new StringBuilder();
for(int i = 0; i <= aKey.length() - maskedAccountNumber.length() ; i++){
maskBuffer.append(MASK_CHARACTER);
}
return maskedAccountNumber.replace(MASK_CHARACTER, maskBuffer.toString());
Below are the two regulare expressions i used so far:
^.\d{1,3}
.\d{1,3}$
That's fairly easy to do, it's still hard to understand under what circumstances do you want which regex.
Either way, (\d*)\d{4} and replace it with $1****, as seen https://regex101.com/r/uI0zJ6/2
Or \d{4}(\d*) and replace with ****$1 https://regex101.com/r/uI0zJ6/3 .

Regex default value if not found

I would like to supply my regular expression with a 'default' value, so if the thing I was looking for is not found, it will return the default value as if it had found it.
Is this possible to do using regex?
It sounds like you want some sort of regex syntax that says "if the regexp does not match any part of the given string pretend that it matched the following substring: 'foobar'". Such a feature does not exist in any regexp syntax I've seen.
You'll probably need to something like this:
matched_string = string.find_regex_match(regex);
if(matched_string == null) {
string = "default";
}
(This will of course need to be adjusted to the language you're using)
It's hard to answer this without a specific language, but in Perl at least, something like this works:
$string='hello';
$default = 1234;
($match) = ($string =~ m/(\d+)/ or $default);
print "$match\n";
1234
Not strictly part of the regex, but avoids the extra conditional block.
As far as I know, you can't do that with RegExp`s, at least with Perl Compatible Regular Expressions.
You can see by your self here.
Here's what I did in javascript...
function match(regx, str, dflt, index = 0) {
if (!str) return dflt
let x = str.match(regx)
return x ? x[index] || dflt : dflt
}