^ and $ in Java regular expression - java

I know that ^ and $ means "matches the beginning of the line" and "matches the end of line"
However, when I did some coding today, I didn't notice any difference between including them and excluding them in a regular expression used in Java.
For example, I want to match a positive Integer using
^[1-9]\\d*$
, and when I exclude them in the regular expression like
[1-9]\\d*
, it seems that there is no difference. I have tried to test with a String that "contains" an integer like ###123###, and the second regular expression can still recognize it is not valid like the first one.
So are the two regular expressions above completely equal to the other one? Thanks!

Do you need to search a string like 2343, or [SPACE]2345, or abc234?
The anchored regex will only find the number in the first string. The un-anchored will find them in all strings.
It all depends on what your requirements are. Are you analyzing lines in a text file, where each line contains only digits?, or are you analyzing the text in a prose document or source-code, where digits may be interspersed among a whole bunch of other stuff?
In the former case, the anchors are good. In the latter, they are bad.
More info: http://www.regular-expressions.info/anchors.html

They are different, the first input checks the whole line so from the begin to the end of the line and second doesn't care about the line.
For more check: regex-bounds

Well...no, the regular expressions aren't equivalent. They're also not doing what you think they are.
You intend to match a positive digit - what your regular expression aims to do is to match some character between 1 and 9, then match any number of digit characters after that (which includes zero).
The difference between the two is the anchoring, as you've noted - the first regex will only match values that literally begin with a 1 through 9, then zero or more digits, then expect there to be nothing else in the string.
The correct regex to match any positive number anywhere in the string would look like this:
[1-9]*\\d*
...and the correct regex to match any line that is a positive number would be this:
^[1-9]*\\d*$

Related

Regular expression non-greedy but still

I have some larger text which in essence looks like this:
abc12..manycharshere...hi - abc23...manyothercharshere...jk
Obviously there are two items, each starting with "abc", the numbers (12 and 23) are interesting as well as the "hi" and "jk" at the end.
I would like to create a regular expression which allows me to parse out the numbers, but only if the two characters at the end match, i.e. I am looking for the number related to "jk", but the following regular expression matches the whole string and thus returns "12", not "23" even when non-greedy matching the area with the following:
abc([0-9]+).*?jk
Is there a way to construct a regular expression which matches text like the one above, i.e. retrieving "23" for items ending in "jk"?
Basically I would need something like "match abc followed by a number, but only if there is "jk" at the end before another instance of "abc followed by a number appears"
Note: the texts/matches are an abstraction here, the actual text is more complicated, espially the things that can appear as "manyothercharactershere", I simplified to show the underlying problem more clearly.
Use a regex like this. .*abc([0-9]+).*?jk
demo here
I think you want something like this,
abc([0-9]+)(?=(?:(?!jk|abc[0-9]).)*jk)
DEMO
You need to use negative lookahead here to make it work:
abc(?!.*?abc)([0-9]+).*?jk
RegEx Demo
Here (?!.*?abc) is negative lookahead that makes sure to match abc where it is NOT followed by another abc thus making sure closes string between abc and jk is matched.
Being non-greedy does not change the rule, that the first match is returned. So abc([0-9]+).*?jk will find the first jk after “abcnumber” rather than the last one, but still match the first “abcnumber”.
One way to solve this is to tell that the dot should not match abc([0-9]+):
abc([0-9]+)((?!abc([0-9]+)).)*jk
If it is not important to have the entire pattern being an exact match you can do it simpler:
.*(abc([0-9]+).*?jk)
In this case, it’s group 1 which contains your intended match. The pattern uses a greedy matchall to ensure that the last possible “abcnumber” is matched within the group.
Assuming that hyphen separates "items", this regex will capture the numbers from the target item:
abc([0-9]+)[^-]*?jk
See demo

Regex index 0 how it exactly works

By compiling the following:
System.out.println(Pattern.matches(".?(\\d)$","3"));
It returns true because before 3 there is nothing and ? check for a one or zero.
However 3 is already the first character of the input which starts at 0 and end at 1. How can the jvm recognize that there is nothing before 3.
For example the following.
System.out.println(Pattern.matches(".*","hello");
It returns true as well but only the very last character gets matched with "nothing".
There should not be a "nothing" character at the beginning of a string, only at the end of it right?
This is not really about the JVM. This is about Java regular expressions.
The regular expression ".*" means "match 0 or more characters". It's easy to satisfy this, since a blank string has 0 characters, and therefore satisfies this. Whether Java regular expressions will choose to be lazy and match an empty string, or to be greedy and match the entire string depends on the implementation of Java regular expressions. If you read this excellent writeup (http://docs.oracle.com/javase/tutorial/essential/regex/quant.html) you can see that patterns like ".*" in Java are considered "reluctant" quantifiers and will prefer to take as little as possible.
Based on the information in that writeup, you can see that a pattern like ".{0,}" is a greedy version of the same expression. Perhaps you'd like to use that instead if this is truly a problem for you.
You are not interpreting your regex correctly. There is no such thing as a "nothing character" . Rather, your pattern reads: any charachter followed by a digit at the end of the string OR a digit at the end of the string.
And surely, "3" fits the second description very well.
matches method tries to match the input exactly.
so there's no need to use ^,$..

Need regular expression for pattern this

I need a regular expression for below pattern
It can start with / or number
It can only contain numbers, no text
Numbers can have space in between them.
It can contain /*, at least 1 number and space or numbers and /*
Valid Strings:
3232////33 43/323//
3232////3343/323//
/3232////343/323//
Invalid Strings:
/sas/3232/////dsds/
/ /34343///// /////
///////////
My Problem is, it can have space between numbers like /3232 323/ but not / /.
How to validate it ?
I have tried so far:
(\\d[\\d ]*/+) , (/*\\d[\\d ]*/+) , (/*)(\\d*)(/*)
This regex should work for you:
^/*(?:\\d(?: \\d)*/*)+$
Live Demo: http://www.rubular.com/r/pUOYFwV8SQ
My solution is not so simple but it works
^(((\d[\d ]*\d)|\d)|/)*((\d[\d ]*\d)|\d)(((\d[\d ]*\d)|\d)|/)*$
Just use lookarounds for the last criteria.
^(?=.*?\\d)([\\d/]*(?:/ ?(?!/)|\\d ?))+$
The best would have been to use conditional regex, but I think Java doesn't support them.
Explanation:
Basically, numbers or slashes, followed by one number and a space, or one slash and a space which is not followed by another slash. Repeat that. The space is made optional because I assume there's none at the end of your string.
Try this java regex
/*(\\d[\\d ]*(?<=\\d)/+)+
It meets all your criteria.
Although you didn't specifically state it, I have assumed that a space may not appear as the first or last character for a number (ie spaces must be between numbers)
"(?![A-z])(?=.*[0-9].*)(?!.*/ /.*)[0-9/ ]{2,}(?![A-z])"
this will match what you want but keep in mind it will also match this
/3232///// from /sas/3232/////dsds/
this is because part of the invalid string is correct
if you reading line by line then match the ^ $ and if you are reading an entire block of text then search for \r\n around the regex above to match each new line

Regular expression to match a character only once before any whitespace

In Java, what regular expression would I use to match a string that has exactly one colon and makes sure that the colon appears before any whitespace?
For example, it should match these strings:
label: print "Enter input"
But: I still had the money.
ghjkdhfjkgjhalergfyujhrageyjdfghbg:
area:54
But not
label: print "Enter input:"
There was one more thing: I still had the money.
ghfdsjhgakjsdhfkjdsagfjkhadsjkhflgadsjklfglsd
area::54
If you use it with matches (which requires to match the entire string), you could use
[^\\s:]*:[^:]*
Which means: arbitrarily many non-whitespace, non-: characters, then a :, then more arbitrarily many non-: characters.
I've really only used two regex concepts: (negated) character classes and repetition.
If you want to require at least one character before or after :, replace the corresponding * with + (as jlordo pointed out in a comment).
The following should work:
^[^\s:]*:(?!.*:)
If your strings can contain line breaks, use the DOTALL flag or change the regex to the following:
(?s)^[^\s:]*:(?!.*:)
It depends on what we call white space, it could be
[^\\p{Space}:]*:[^:]
The following should get you started:
Matcher MatchedPattern = Pattern.compile("^(\\w+\\:{1}[\"\\w\\s\\.]*)$").matcher("yourstring");

How can I express such requirement using Java regular expression?

I need to check that a file contains some amounts that match a specific format:
between 1 and 15 characters (numbers or ",")
may contains at most one "," separator for decimals
must at least have one number before the separator
this amount is supposed to be in the middle of a string, bounded by alphabetical characters (but we have to exclude the malformed files).
I currently have this:
\d{1,15}(,\d{1,14})?
But it does not match with the requirement as I might catch up to 30 characters here.
Unfortunately, for some reasons that are too long to explain here, I cannot simply pick a substring or use any other java call. The match has to be in a single, java-compatible, regular expression.
^(?=.{1,15}$)\d+(,\d+)?$
^ start of the string
(?=.{1,15}$) positive lookahead to make sure that the total length of string is between 1 and 15
\d+ one or more digit(s)
(,\d+)? optionally followed by a comma and more digits
$ end of the string (not really required as we already checked for it in the lookahead).
You might have to escape backslashes for Java: ^(?=.{1,15}$)\\d+(,\\d+)?$
update: If you're looking for this in the middle of another string, use word boundaries \b instead of string boundaries (^ and $).
\b(?=[\d,]{1,15}\b)\d+(,\d+)?\b
For java:
"\\b(?=[\\d,]{1,15}\\b)\\d+(,\\d+)?\\b"
More readable version:
"\\b(?=[0-9,]{1,15}\\b)[0-9]+(,[0-9]+)?\\b"

Categories

Resources