Regex for checking whole multiline text in angularjs

I need help.
I have to create a regex for the angularjs ng-pattern attribute. The regular expression should check the text, not every line or some fragments. The text should contain some amounts with exactly 2 decimal places, and each amount should be entered on a new line. In addition, spaces are accepted before and after each amount. If one line contains 2 sums, all text is invalid.

For example, this text is valid because each amount is entered on a new line:

123.34 12345.56 2.54 

This example is not valid because one line contains 2 sums:

 12.43 123.32 2345.54 124.43 

This example is invalid because one sum does not contain 2 decimal numbers (each sum must be exactly 2 decimal places):

 123 123.43 123.65 

My best attempt is ^(([0-9]+[.][0-9]{2})\s*)+$ , and it can be tested here . But my regular expression is not enough, because it takes text with several sums in one line.

thanks

+5
source share
4 answers

you can use

 ng-pattern="/^[^\S\r\n]*\d+\.\d{2}(?:[^\S\r\n]*\r?\n[^\S\r\n]*\d+\.\d{2})*[^\S\r\n]*$/" 

See the demo of regex .

Or, since angular truncates the input before sending it to the default regular expression engine (if you don't have ng-trim or if you have ng-trim="true" ), you can also use

 ng-pattern="/^\d+\.\d{2}(?:[^\S\r\n]*\r?\n[^\S\r\n]*\d+\.\d{2})*$/" 

Or, if you want to make sure there are no empty lines at the beginning and end, use the first regular expression with ng-trim="false" .

Template Details

  • ^ - start of line
  • [^\S\r\n]* - any horizontal spaces 0+
  • \d+ - 1 or more digits
  • \. - a . char
  • \d{2} - 2 digits
  • (?: - the beginning of the comparison of the group not related to the capture ...
    • [^\S\r\n]* - any horizontal spaces 0+
    • \r?\n - line break sequence
    • [^\S\r\n]*\d+\.\d{2} - any horizontal spaces 0+, 1 + digits,. and 2 digits
  • )* -... zero or more times
  • [^\S\r\n]* - any horizontal spaces 0+
  • $ is the end of the line.
+3
source

Regex is not my forte, so there may be a much simpler way to do this, but it fits your requirements:

 ^(([^\S\r\n]*[0-9]+[.][0-9]{2}[^\S\r\n]*)\n)*(([^\S\r\n]*[0-9]+[.][0-9]{2}[^\S\r\n]*))$ 

Effectively, what he does is to ensure that the last line (without a newline at the end) is always present, but also allows extra lines to those that end with a new line (\ n).

We also use the [^\S\r\n] part instead of \s to make sure that it checks for whitespace, excluding a new line, since a new line causes a problem with checking multiple values ​​on a single line.

Here is a working example

+6
source

the problem is that \s also matches spaces, using [\r\n] instead of matching news and caries returns.

EDIT my first message mentioned \R , but it is specific to PCRE.

EDIT the following comments to accept also a space at the end of the line

 ^(([0-9]+[.][0-9]{2}) *(?:\r?\n|$))+$ 

regex101

+1
source

add a multi-line flag /m to be able to bind ^ to the beginning of each line

/^([0-9]+[.][0-9]{2})\s*$/gm

eg. https://regex101.com/r/XMTSok/4

+1
source

Source: https://habr.com/ru/post/1275122/


All Articles