问题
I am looking for a Regex to match a string which should:
- start with an optional
978-or979-prefix - continue with a digit
- have a permutation of exactly 7 digits and 2 hyphens, without 2 consecutive hyphens
- end with a sequence of digit, hyphen, digit (which can be an
x)
NB.: Hyphens can be replaced (coherently) by spaces or not present altogether...
Match:
- 9780309091695
- 0309091695
- 9790309091695
- 978030909169x
- 978-0-309-09169-5
- 978-1-84356-028-3
- 978-0-8044-2957-X
- 978-93-86954-21-4
- 978-0-943396-04-2
- 978-0-9752298-0-X
- 978-99921-58-10-7
- 978-9971-5-0210-0
- 978-960-425-059-0
- 978-80-902734-1-6
- 978-85-359-0277-5
- 978 0 309 09169 5
No Match:
- 978030909169
- 97803090916951
- 030909169
- 03090916951
- 978-0--30909169-5
- 978 0 309 09169 5
- 978 0-309 09169-5
- 978-0-309-091695-
My current proposition is thanks to answers I had to a previous question and should be able to be further simplified: /^((97(8|9))*\d{9}|(97(8|9)-)*(?=.{11}-)(?:\d+-){3}|(97(8|9) )*(?=.{11} )(?:\d+ ){3})[\dx]$/i
回答1:
You may try:
^(?:97[89])?([- ]?)(?=(?:\d\1?){9}\1[\dxX]$)(?:\d+\1){3}[\dxX]
See the online demo
^- Start string anchor.(?:- Open non-capture group:97[89]- Match "97" followed by either an 8 or 9.)?- Close non-capture group and make it optional.
(- Open 1st capture group:[- ]?- Optionally match an hyphen or space.)- Close 1st capture group.
(?=- Open positive lookahead:(?:- Open non-capture group:\d\1?- Capture a digit and optionally match what is captured in the 1st capture group.){9}- Close the non-capture group and match it nine times (to assert a position with 9 digits ahead).
\1[\dxX]$- Again match what is captured in the 1st capture group followed by a digit or lower- or uppercase "x" and the end string anchor.)- Close positive lookahead.
(?:- Open non-capture group:\d+\1- 1+ digits followed by what is captured in the 1st capture group.){3}- Close the non-capture group and match it three times.
[\dxX]- Match a digit, a lower- or uppercase "x".
回答2:
This value is at both match and not match 978 0 309 09169 5. I think it should be matched as it has the same prefix, 10 digits and same amount of delimiters.
Another option could be matching an optional prefix and either 10 digits or the part with the delimiters using an alternation |
You could capture an optional space or hyphen in group 1 using ([- ])? and refer to it using a backreference \1 to keep the delimiters consistent.
^(?:97[89]([- ])?)?(?:\d{10}|(?=(?:\d\1?){9}\1?[xX\d]$)\d+(?:\1?\d+){2}\1?[\dxX])$
Explanation
^Start of sting(?:97[89]([- ])?)?Optionally match the prefix and capture optional hyphen in group 1(?:Non capture group\d{10}Match 10 digits|Or(?=(?:\d\1?){9}\1?[xX\d]$)Positive lookahead, assert 9 digits followed by an optional delimiter and eitherxXor a digit till the end of the string\d+(?:\1?\d+){2}Match 1+ digits and repeat 2 times matching an optional delimiter and 1+ digits-?[\dxX]Match optional-and eitherxXor a digit
)Close non capture group$End of string
Regex demo
来源:https://stackoverflow.com/questions/65925071/regex-to-extend-isbn-10-and-isbn-13-to-non-english-speaking-countries