简体   繁体   中英

Regular expression to match numbers

I am looking for a regular expression regex to match one of these patterns:

  • Number followed by x
  • Number separated by one or more space

I don't know if match is the correct method to achieve the results.

Matching examples:

' 30x '
'30x'
'20 30'
' 20 30 '

'30x'.match(regex).to_a #=> ['30']
'30 40'.match(regex).to_a #=> ['30', '40']
"30".match(regex).to_a # => ["30"]
" 30 ".match(regex).to_a # => ["30"]
"30 40".match(regex).to_a # => ["30", "40"]

Non-matching examples:

'20x 30 '
'x20 '

"30xx".match(regex).to_a # => nil
"30 a".match(regex).to_a # => nil
"30 60x".match(regex).to_a # => nil
"30x 20".match(regex).to_a # => nil

EDIT

Following @TeroTilus advice, this is the use case for this question:

The user will insert how he will pay an debt. Then, we've created a textfield to easily insert the payment condition. Example:

 > "15 20" # Generate 2 bills: First for 15 days and second for 20 days
 > "2x" # Generate 2 bills: First for 30 days and second for 60 days 
 > "2x 30" # Show message of 'Invalid Format'
 > "ANY other string" # Show message of 'Invalid Format'

How about:

/^\s*\d+(?:x\s*|\s*\d+)?$/

explanation:

The regular expression:

(?-imsx:^\s*\d+(?:x\s*|\s*\d+)?$)

matches as follows:

NODE                     EXPLANATION
----------------------------------------------------------------------
(?-imsx:                 group, but do not capture (case-sensitive)
                         (with ^ and $ matching normally) (with . not
                         matching \n) (matching whitespace and #
                         normally):
----------------------------------------------------------------------
  ^                        the beginning of the string
----------------------------------------------------------------------
  \s*                      whitespace (\n, \r, \t, \f, and " ") (0 or
                           more times (matching the most amount
                           possible))
----------------------------------------------------------------------
  \d+                      digits (0-9) (1 or more times (matching
                           the most amount possible))
----------------------------------------------------------------------
  (?:                      group, but do not capture (optional
                           (matching the most amount possible)):
----------------------------------------------------------------------
    x                        'x'
----------------------------------------------------------------------
    \s*                      whitespace (\n, \r, \t, \f, and " ") (0
                             or more times (matching the most amount
                             possible))
----------------------------------------------------------------------
   |                        OR
----------------------------------------------------------------------
    \s*                      whitespace (\n, \r, \t, \f, and " ") (0
                             or more times (matching the most amount
                             possible))
----------------------------------------------------------------------
    \d+                      digits (0-9) (1 or more times (matching
                             the most amount possible))
----------------------------------------------------------------------
  )?                       end of grouping
----------------------------------------------------------------------
  $                        before an optional \n, and the end of the
                           string
----------------------------------------------------------------------
)                        end of grouping
----------------------------------------------------------------------

试试string.scan(/(^|\\s+)(\\d+)x?/).map(&:last) ,它可能会做您想要的。

This should work for the examples you gave.

^(?:\\s*(\\d+))+x?\\s*$

^     # Match start of string
(?:   # Open non-capturing group
\s*   # Zero or more spaces at start or between numbers
(\d+) # Capture one or more numbers
)     # Close the group
+     # Group should appear one or more times
x?    # The final group may have an x directly after it
\s*   # Zero or more trailing spaces are allowed
$     # Match the end of the string

Edited to capture the numbers, not sure if you were looking to do this or just match the string.

这对我有用

\\d*x\\s*$|\\d*[^x] \\d[^\\s]*

I have newer written a single line of ruby so the syntax of the below might be horible

But, the easiest solution to your problem is; first reduce your first case to your second case, then do your matching for numbers.

Something like;

("20x 30".gsub/^\s*(\d+)x\s*$/,'\1').match(/\b\d+\b/)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM