นิพจน์ทั่วไปสำหรับตัวเลขทศนิยม


117

ฉันมีงานที่ต้องจับคู่ตัวเลขทศนิยม ฉันได้เขียนนิพจน์ทั่วไปต่อไปนี้สำหรับมัน:

[-+]?[0-9]*\.?[0-9]*

แต่ส่งกลับข้อผิดพลาด:

Invalid escape sequence (valid ones are  \b  \t  \n  \f  \r  \"  \'  \\ )

ตามความรู้ของฉันเราจำเป็นต้องใช้อักขระหลบหนีสำหรับสิ่ง.นี้ด้วย โปรดแก้ไขฉันว่าฉันผิดตรงไหน


10
regex นี้ใช้ภาษาอะไร
CaffGeek

3
@JDB - ทำไมคุณถึงให้ 100 คะแนนสำหรับตัวเลข / ทศนิยม? มาตรฐานได้รับมาโดยตลอด(?:\d+(?:\.\d*)?|\.\d+)และได้รับการโพสต์โฆษณา infinitum บน SO ...


1
[-+]?([0-9]*[.])?[0-9]+([eE][-+]?\d+)?หากคุณต้องการจับสัญกรณ์เอกซ์โพเนนเชียลด้วย e, g, 3.023e-23
wcochran

ในบางภาษาเช่น Java หรือ C ++ แบ็กสแลชต้องเป็นค่า Escape เพื่อให้ได้นิพจน์ทั่วไป "\." คุณจะต้องใช้สตริง "\\." Python หลีกเลี่ยงสิ่งนี้โดยใช้สตริงดิบ
HackerBoss

คำตอบ:


260

TL; ดร

ใช้[.]แทน\.และ[0-9]แทนที่จะ\dหลีกเลี่ยงปัญหาในบางภาษา (เช่น Java)

ขอบคุณบุคคลนิรนามที่รับรู้สิ่งนี้ตั้งแต่แรก

รูปแบบที่ค่อนข้างง่ายสำหรับการจับคู่เลขทศนิยมคือ

[+-]?([0-9]*[.])?[0-9]+

สิ่งนี้จะตรงกับ:

  • 123
  • 123.456
  • .456

ดูตัวอย่างการทำงาน

หากคุณต้องการจับคู่123.(จุดที่ไม่มีส่วนทศนิยม) คุณจะต้องมีนิพจน์ที่ยาวขึ้นเล็กน้อย:

[+-]?([0-9]+([.][0-9]*)?|[.][0-9]+)

ดูคำตอบของ pkellerสำหรับคำอธิบายที่ครบถ้วนยิ่งขึ้นเกี่ยวกับรูปแบบนี้

หากคุณต้องการรวมตัวเลขที่ไม่ใช่ทศนิยมเช่นฐานสิบหกและฐานแปดดูคำตอบของฉันฉันจะระบุได้อย่างไรว่าสตริงเป็นตัวเลข .

หากคุณต้องการตรวจสอบว่าอินพุตเป็นตัวเลข (แทนที่จะค้นหาตัวเลขภายในอินพุต) คุณควรล้อมรอบรูปแบบด้วย^และ$ดังนี้:

^[+-]?([0-9]+([.][0-9]*)?|[.][0-9]+)$

นิพจน์ทั่วไปที่ผิดปกติ

"การแสดงออกปกติ" ในขณะที่การดำเนินการในภาษาที่ทันสมัยที่สุด, APIs, กรอบ, ห้องสมุด, ฯลฯ อยู่บนพื้นฐานของแนวคิดการพัฒนาในทฤษฎีภาษาอย่างเป็นทางการ อย่างไรก็ตามวิศวกรซอฟต์แวร์ได้เพิ่มส่วนขยายจำนวนมากที่นำการใช้งานเหล่านี้ไปใช้เกินกว่าคำจำกัดความที่เป็นทางการ ดังนั้นในขณะที่เอ็นจิ้นนิพจน์ทั่วไปส่วนใหญ่มีลักษณะคล้ายกัน แต่ก็ไม่มีมาตรฐาน ด้วยเหตุนี้จำนวนมากจึงขึ้นอยู่กับภาษา API กรอบงานหรือไลบรารีที่คุณใช้

(อนึ่งเพื่อช่วยลดความสับสนหลายคนจึงใช้ " regex " หรือ " regexp " เพื่ออธิบายภาษาที่จับคู่ขั้นสูงเหล่านี้ดูRegex เหมือนกับนิพจน์ทั่วไปหรือไม่ที่ RexEgg.com สำหรับข้อมูลเพิ่มเติม)

ที่กล่าวว่าเครื่องมือ regex มากที่สุด (ที่จริงทั้งหมดของพวกเขาเท่าที่ฉันรู้) \.จะยอมรับ เป็นไปได้มากว่ามีปัญหาในการหลบหนี

ปัญหาในการหลบหนี

บางภาษามีในตัวสนับสนุนสำหรับ regexes, เช่น JavaScript สำหรับภาษาที่ไม่มีการหลีกเลี่ยงอาจเป็นปัญหาได้

นี่เป็นเพราะโดยพื้นฐานแล้วคุณกำลังเข้ารหัสภาษาภายในภาษา ตัวอย่างเช่น Java ใช้\เป็นอักขระหลีกภายในสตริงดังนั้นหากคุณต้องการวางอักขระแบ็กสแลชตามตัวอักษรภายในสตริงคุณต้องหลีกเลี่ยง:

// creates a single character string: "\"
String x = "\\";

อย่างไรก็ตาม regexes ยังใช้\อักขระในการหลีกเลี่ยงดังนั้นหากคุณต้องการจับคู่\อักขระตามตัวอักษรคุณต้องหลีกเลี่ยงสำหรับเอนจิน regexe จากนั้นจึงหลีกเลี่ยงอีกครั้งสำหรับ Java:

// Creates a two-character string: "\\"
// When used as a regex pattern, will match a single character: "\"
String regexPattern = "\\\\";

ในกรณีของคุณคุณอาจไม่ได้หลีกหนีอักขระแบ็กสแลชในภาษาที่คุณกำลังเขียนโปรแกรม:

// will most likely result in an "Illegal escape character" error
String wrongPattern = "\.";
// will result in the string "\."
String correctPattern = "\\.";

การหลบหนีทั้งหมดนี้อาจสร้างความสับสนได้มาก หากภาษาที่คุณใช้งานรองรับสตริงดิบคุณควรใช้ภาษาเหล่านี้เพื่อลดจำนวนแบ็กสแลช แต่ไม่ใช่ทุกภาษาที่ทำ (โดยเฉพาะอย่างยิ่ง: Java) โชคดีที่มีทางเลือกอื่นที่จะได้ผลในบางครั้ง:

String correctPattern = "[.]";

สำหรับเอนจิ้น regex \.และ[.]หมายความว่าเหมือนกันทุกประการ โปรดทราบว่าวิธีนี้ใช้ไม่ได้ในทุกกรณีเช่นขึ้นบรรทัดใหม่ ( \\n) วงเล็บเหลี่ยมเปิด ( \\[) และแบ็กสแลช ( \\\\หรือ[\\])

หมายเหตุเกี่ยวกับการจับคู่หมายเลข

(คำใบ้: มันยากกว่าที่คุณคิด)

การจับคู่ตัวเลขเป็นหนึ่งในสิ่งที่คุณคิดว่าค่อนข้างง่ายสำหรับ regex แต่จริงๆแล้วมันค่อนข้างยุ่งยาก ลองมาดูแนวทางของคุณทีละชิ้น:

[-+]?

จับคู่ตัวเลือก-หรือ+

[0-9]*

จับคู่ตัวเลขตามลำดับ 0 หรือมากกว่า

\.?

จับคู่ตัวเลือก .

[0-9]*

จับคู่ตัวเลขตามลำดับ 0 หรือมากกว่า

ขั้นแรกเราสามารถล้างนิพจน์นี้ได้เล็กน้อยโดยใช้ไฟล์ ชวเลขคลาสอักขระสำหรับตัวเลข (โปรดทราบว่าสิ่งนี้มีความอ่อนไหวต่อปัญหาการหลบหนีที่กล่าวถึงข้างต้นด้วย):

[0-9] = \d

ฉันจะใช้\dด้านล่าง [0-9]แต่เก็บไว้ในใจว่ามันหมายถึงสิ่งเดียวกันเช่น (จริงๆแล้วในเครื่องยนต์บางรุ่น\dจะจับคู่ตัวเลขจากสคริปต์ทั้งหมดดังนั้นมันจะตรงมากกว่าที่[0-9]จะต้องการ แต่นั่นอาจไม่สำคัญในกรณีของคุณ)

ตอนนี้ถ้าคุณดูที่นี้อย่างคุณจะรู้ว่าทุกส่วนหนึ่งของรูปแบบของคุณเป็นตัวเลือก รูปแบบนี้สามารถจับคู่สตริงความยาว 0 สตริงที่ประกอบด้วย+หรือ- ; หรือสตริงที่ประกอบด้วย.. นี่อาจไม่ใช่สิ่งที่คุณตั้งใจไว้

ในการแก้ไขปัญหานี้การเริ่มต้นด้วยการ "ยึด" regex ของคุณด้วยสตริงขั้นต่ำที่กำหนดจะเป็นประโยชน์ซึ่งอาจเป็นตัวเลขหลักเดียว:

\d+

ตอนนี้เราต้องการเพิ่มส่วนทศนิยม แต่มันไม่ไปในที่ที่คุณคิดว่ามันอาจ:

\d+\.?\d* /* This isn't quite correct. */

123.นี้จะยังคงตรงกับค่าเช่น ที่แย่กว่านั้นคือมีความชั่วร้ายเกี่ยวกับเรื่องนี้ ช่วงเวลาเป็นทางเลือกซึ่งหมายความว่าคุณมีคลาสซ้ำสองคลาสแบบเคียงข้างกัน ( \d+และ\d*) สิ่งนี้อาจเป็นอันตรายได้หากใช้ในทางที่ผิดโดยจะเปิดระบบของคุณไปสู่การโจมตี DoS

ในการแก้ไขปัญหานี้แทนที่จะถือว่าช่วงเวลาเป็นทางเลือกเราจำเป็นต้องปฏิบัติตามที่กำหนด (เพื่อแยกคลาสอักขระที่ซ้ำกัน) และทำให้ส่วนทศนิยมทั้งหมดเป็นทางเลือก:

\d+(\.\d+)? /* Better. But... */

ตอนนี้ดูดีขึ้นแล้ว เราต้องการช่วงเวลาระหว่างตัวเลขลำดับแรกและลำดับที่สอง แต่มีข้อบกพร่องร้ายแรง: เราไม่สามารถจับคู่ได้.123เนื่องจากต้องใช้เลขนำหน้า

นี่เป็นเรื่องง่ายที่จะแก้ไข แทนที่จะทำให้ส่วน "ทศนิยม" ของตัวเลขเป็นทางเลือกเราจำเป็นต้องพิจารณาให้เป็นลำดับของอักขระ: ตัวเลข 1 ตัวขึ้นไปที่อาจนำหน้าด้วยตัวเลข.ที่อาจนำหน้าด้วย 0 หรือมากกว่า:

(\d*\.)?\d+

ตอนนี้เราเพิ่มเครื่องหมาย:

[+-]?(\d*\.)?\d+

แน่นอนว่าเครื่องหมายทับเหล่านี้ค่อนข้างน่ารำคาญใน Java ดังนั้นเราจึงสามารถแทนที่ในคลาสอักขระแบบยาวได้:

[+-]?([0-9]*[.])?[0-9]+

การจับคู่เทียบกับการตรวจสอบความถูกต้อง

สิ่งนี้เกิดขึ้นในความคิดเห็นสองสามครั้งดังนั้นฉันจึงเพิ่มภาคผนวกเกี่ยวกับการจับคู่กับการตรวจสอบความถูกต้อง

เป้าหมายของการจับคู่คือการค้นหาเนื้อหาบางส่วนในอินพุต ("เข็มในกองหญ้า") เป้าหมายของการตรวจสอบความถูกต้องคือเพื่อให้แน่ใจว่าอินพุตอยู่ในรูปแบบที่คาดหวัง

โดยธรรมชาติ Regexes จะจับคู่ข้อความเท่านั้น เมื่อป้อนข้อมูลบางส่วนพวกเขาจะพบข้อความที่ตรงกันหรือจะไม่พบ อย่างไรก็ตามด้วยการ "snapping" นิพจน์ไปยังจุดเริ่มต้นและจุดสิ้นสุดของอินพุตที่มีแท็ก anchor ( ^และ$) เราสามารถมั่นใจได้ว่าจะไม่พบรายการที่ตรงกันเว้นแต่ว่าอินพุตทั้งหมดจะตรงกับนิพจน์โดยใช้ regexes เพื่อตรวจสอบความถูกต้องตรวจสอบ

regex ที่อธิบายไว้ข้างต้น ( [+-]?([0-9]*[.])?[0-9]+) จะจับคู่ตัวเลขอย่างน้อยหนึ่งตัวภายในสตริงเป้าหมาย ดังนั้นให้ป้อนข้อมูล:

apple 1.34 pear 7.98 version 1.2.3.4

regex จะตรง1.34, 7.98, 1.2, .3และ.4และ

ในการตรวจสอบว่าอินพุตที่ระบุเป็นตัวเลขและไม่มีอะไรนอกจากตัวเลขให้ "สแนป" นิพจน์ไปที่จุดเริ่มต้นและจุดสิ้นสุดของอินพุตโดยการรวมไว้ในแท็กจุดยึด:

^[+-]?([0-9]*[.])?[0-9]+$

สิ่งนี้จะค้นหารายการที่ตรงกันก็ต่อเมื่ออินพุตทั้งหมดเป็นตัวเลขทศนิยมและจะไม่พบข้อมูลที่ตรงกันหากอินพุตมีอักขระเพิ่มเติม ดังนั้นเมื่อป้อนข้อมูล1.2แล้วจะพบapple 1.2 pearรายการที่ตรงกันแต่จะไม่พบรายการที่ตรงกัน

ทราบว่าบางส่วนเครื่องยนต์ regex มีvalidate, isMatchหรือฟังก์ชั่นที่คล้ายกันซึ่งเป็นหลักไม่สิ่งที่ฉันได้อธิบายไว้โดยอัตโนมัติกลับtrueถ้าการแข่งขันถูกพบและfalseหากไม่มีการแข่งขันพบ นอกจากนี้โปรดทราบว่าเอ็นจิ้นบางตัวอนุญาตให้คุณตั้งค่าแฟล็กซึ่งเปลี่ยนนิยามของ^และ$จับคู่จุดเริ่มต้น / จุดสิ้นสุดของบรรทัดแทนที่จะเป็นจุดเริ่มต้น / จุดสิ้นสุดของอินพุตทั้งหมด โดยทั่วไปนี่ไม่ใช่ค่าเริ่มต้น แต่โปรดระวังแฟล็กเหล่านี้


2
JDB ขอบคุณและฉันหวังว่าคุณจะยังอยู่! ฉันกำลังอ่านโพสต์ของคุณในอนาคต :) คำตอบของคุณดูแล 0.24 และ 2.2 และปิดการใช้งาน 4.2.44 อย่างถูกต้องทั้งหมดทดสอบด้วยregex101.comอย่างไรก็ตามไม่อนุญาต 123 ซึ่งตามที่คุณพูดอาจเป็นที่ยอมรับ (และฉันคิดว่ามัน คือ!). ฉันสามารถแก้ไขได้โดยเปลี่ยนนิพจน์ของคุณเป็น [- +]? (\ d * [.])? \ d * (สังเกต * ที่ท้ายแทนที่จะเป็น +) แต่สิ่งที่บ้าคลั่งเช่น (ตัวอย่างที่สองของคุณ) ได้รับอนุญาต จะเอาเค้กของฉันไปกินด้วยเหรอ?
Dave

2
@Dave -\d+(\.\d*)?|\.\d+
JDB ยังจำโมนิกา

/[-+]?(\d*[.])?\d+/.test("1.bc") // returns true
yeouuu

1
@yeouuu ใช่เพราะ1.ตรงกัน เพิ่ม^และ$ไปยังจุดเริ่มต้นและจุดสิ้นสุดของ regex หากคุณต้องการจับคู่ก็ต่อเมื่ออินพุตทั้งหมดตรงกัน
JDB ยังคงจำ Monica ได้

5
ลอยสามารถมีเลขชี้กำลังหรือเป็น NaN / Inf ได้ดังนั้นฉันจะใช้สิ่งนี้: [-+]?(([0-9]*[.]?[0-9]+([ed][-+]?[0-9]+)?)|(inf)|(nan))e / d สำหรับการลอยตัวแบบลอย / ความแม่นยำสองเท่า อย่าลืมแฟ
ล็

23

ฉันไม่คิดว่าคำตอบใด ๆ ในหน้านี้ในขณะที่เขียนนั้นถูกต้อง (คำแนะนำอื่น ๆ ใน SO ก็ผิดด้วยเช่นกัน) ภาวะแทรกซ้อนคือคุณต้องจับคู่ความเป็นไปได้ทั้งหมดต่อไปนี้:

  • ไม่มีจุดทศนิยม (เช่นค่าจำนวนเต็ม)
  • ตัวเลขทั้งก่อนและหลังจุดทศนิยม (เช่น0.35, 22.165)
  • ตัวเลขก่อนจุดทศนิยมเท่านั้น (เช่น0., 1234.)
  • ตัวเลขหลังจุดทศนิยมเท่านั้น (เช่น.0, .5678)

ในเวลาเดียวกันคุณต้องตรวจสอบให้แน่ใจว่ามีอย่างน้อยหนึ่งหลักอยู่ที่ไหนสักแห่งนั่นคือไม่อนุญาตสิ่งต่อไปนี้:

  • จุดทศนิยมด้วยตัวมันเอง
  • จุดทศนิยมที่ลงนามโดยไม่มีตัวเลข (เช่น+.หรือ-.)
  • +หรือ-ด้วยตัวเอง
  • สตริงว่าง

สิ่งนี้ดูเหมือนจะยุ่งยากในตอนแรก แต่วิธีหนึ่งในการค้นหาแรงบันดาลใจคือดูที่แหล่ง OpenJDK สำหรับjava.lang.Double.valueOf(String)วิธีการ (เริ่มที่http://hg.openjdk.java.net/jdk8/jdk8/jdkคลิก "เรียกดู" นำทางลง/src/share/classes/java/lang/และค้นหาDoubleชั้นเรียน) regex แบบยาวที่คลาสนี้มีให้บริการสำหรับความเป็นไปได้ต่างๆที่ OP อาจไม่ได้คำนึงถึง แต่จะมองข้ามความเรียบง่ายของส่วนที่จัดการกับ NaN, infinity, สัญกรณ์ฐานสิบหกและเลขชี้กำลังและใช้\dแทนสัญกรณ์ POSIX สำหรับ ตัวเลขหลักเดียวฉันสามารถลดส่วนที่สำคัญของนิพจน์ทั่วไปสำหรับเลขทศนิยมที่ลงนามโดยไม่มีเลขชี้กำลังเป็น:

[+-]?((\d+\.?\d*)|(\.\d+))

ฉันไม่คิดว่าจะมีวิธีหลีกเลี่ยงการ(...)|(...)ก่อสร้างโดยไม่อนุญาตให้มีบางสิ่งที่ไม่มีตัวเลขหรือห้ามความเป็นไปได้อย่างใดอย่างหนึ่งที่ไม่มีตัวเลขก่อนจุดทศนิยมหรือไม่มีตัวเลขตามหลัง

เห็นได้ชัดว่าในทางปฏิบัติคุณจะต้องรองรับช่องว่างต่อท้ายหรือนำหน้าไม่ว่าจะใน regex เองหรือในโค้ดที่ใช้


หากคุณเพิ่มข้อกำหนดในการจับคู่ตัวเลขเช่น123.ใช่ ... หรือสวิตช์เป็นทางออกเดียวดังที่ฉันได้ชี้ให้เห็นในความคิดเห็นในโพสต์ต้นฉบับของฉัน
JDB ยังคงจำ Monica

1
คำตอบนี้และคำตอบอื่น ๆ ทั้งหมด / ส่วนใหญ่ไม่สนใจว่า float สามารถมีเลขชี้กำลังได้
NateS

1
@NateS ถูกต้องฉันเขียนว่า "ไม่สนใจเพื่อความเรียบง่ายของส่วนที่จัดการกับ NaN, infinity, สัญกรณ์เลขฐานสิบหกและเลขชี้กำลัง" เพราะดูเหมือนว่าจะตรงกับขอบเขตของคำถามของ OP มีการใช้งานที่สมบูรณ์มากขึ้นรวมถึงสิ่งที่ฉันพบในซอร์สโค้ด JDK
pkeller

1
regex [+-]?((?=\.?\d)\d*\.?\d*)สามารถใช้เพื่อหลีกเลี่ยงการสลับได้หรือไม่? มันใช้ lookahead ...
4esn0k

1
@ 4esn0k ดี regex! ฉันเล่นกับมันแล้วและได้ผล ฉันมีข้อแม้สองประการ: (1) เอ็นจิ้น regex บางตัวไม่รองรับการยืนยันความกว้างเป็นศูนย์ (แม้ว่าอันที่ทันสมัยส่วนใหญ่จะทำ AFAIK) และ (2) การมองไปข้างหน้าเป็นเพียงการสลับชื่ออื่น: เครื่องยนต์ยังคงต้องลองอะไรบางอย่าง และย้อนกลับหากไม่ได้ผล มีการโหวตเพิ่มขึ้นสำหรับความคิดที่เรียบร้อยมากอย่างไรก็ตาม
pkeller

7

สิ่งที่คุณต้องการคือ:

[\-\+]?[0-9]*(\.[0-9]+)?

ฉันหนีเครื่องหมาย "+" และ "-" และยังจัดกลุ่มทศนิยมด้วยตัวเลขต่อไปนี้ตั้งแต่ "1" ไม่ใช่ตัวเลขที่ถูกต้อง

การเปลี่ยนแปลงจะช่วยให้คุณจับคู่จำนวนเต็มและจำนวนทศนิยมได้ ตัวอย่างเช่น:

0
+1
-2.0
2.23442

ปัญหาเกี่ยวกับนิพจน์นี้คือ.1จะไม่ได้รับอนุญาตแม้ว่าอินพุตดังกล่าวจะได้รับการยอมรับในระดับสากลว่าถูกต้อง
JDB ยังคงจำ Monica ได้

ตอนนี้จะยอมรับสตริงที่มีความยาวเป็นศูนย์-และ+ไม่ใช่ตัวเลข Regex เป็นเรื่องยุ่งยาก! :)
JDB ยังจำ Monica ได้

นอกจากนี้ยังไม่ตอบคำถามจริงของ OP ซึ่ง\.ไม่ได้ผล
JDB ยังคงจำ Monica ได้

7

ฉันต้องการจับคู่สิ่งที่ภาษาส่วนใหญ่พิจารณาตัวเลขที่ถูกต้อง (จำนวนเต็มและจำนวนลอย):

  • '5' / '-5'

  • '1.0' / '1.' / '.1' / '-1.' / '-.1'

  • '0.45326e+04', '666999e-05', '0.2e-3', '-33.e-1'

หมายเหตุ:

  • preceding sign of number ('-' or '+') is optional

  • '-1.' and '-.1' are valid but '.' and '-.' are invalid

  • '.1e3' is valid, but '.e3' and 'e3' are invalid

เพื่อรองรับทั้ง '1. ' และ '.1' เราต้องการตัวดำเนินการ OR ('|') เพื่อให้แน่ใจว่าเราไม่รวม '.' จากการจับคู่

[+-]?+/- sing เป็นทางเลือกเนื่องจาก?หมายถึง 0 หรือ 1 แมตช์

( เนื่องจากเรามี 2 นิพจน์ย่อยจึงต้องใส่ไว้ในวงเล็บ

\d+([.]\d*)?(e[+-]?\d+)? สำหรับตัวเลขที่ขึ้นต้นด้วยหลัก

| แยกนิพจน์ย่อย

[.]\d+(e[+-]?\d+)? นี่คือตัวเลขที่ขึ้นต้นด้วย "."

) การสิ้นสุดของนิพจน์

  • สำหรับตัวเลขที่ขึ้นต้นด้วย "."

[.] อักขระตัวแรกคือจุด (ภายในวงเล็บหรือมิฉะนั้นจะเป็นอักขระตัวแทน)

\d+ หนึ่งหลักขึ้นไป

(e[+-]?\d+)? นี่เป็นทางเลือก (0 หรือ 1 ที่ตรงกันเนื่องจากการสิ้นสุด "?") สัญกรณ์ทางวิทยาศาสตร์

  • สำหรับตัวเลขที่ขึ้นต้นด้วยหลัก

\d+ หนึ่งหลักขึ้นไป

([.]\d*)? ทางเลือกที่เราสามารถมีอักขระจุดเป็นศูนย์หรือมากกว่าตัวเลขหลังจากนั้น

(e[+-]?\d+)? นี่เป็นสัญกรณ์ทางวิทยาศาสตร์ที่เป็นทางเลือก

  • สัญกรณ์วิทยาศาสตร์

e ลิเทอรัลที่ระบุเลขชี้กำลัง

[+-]? เครื่องหมายเลขชี้กำลัง

\d+ หนึ่งหลักขึ้นไป

ทั้งหมดที่รวมกัน:

[+-]?(\d+([.]\d*)?(e[+-]?\d+)?|[.]\d+(e[+-]?\d+)?)

ในการยอมรับEเช่นกัน:

[+-]?(\d+([.]\d*)?([eE][+-]?\d+)?|[.]\d+([eE][+-]?\d+)?)

( กรณีทดสอบ )


4

สิ่งนี้ง่ายมาก: คุณใช้ Java แล้วและคุณควรใช้\\.แทน\.(ค้นหาอักขระที่ใช้ Escape ใน Java)


คุณน่าจะถูกต้อง ... ข้อความแสดงข้อผิดพลาดดูเหมือนข้อผิดพลาดทางไวยากรณ์ของภาษาโปรแกรมแทนที่จะเป็นข้อผิดพลาดตัวแยกวิเคราะห์ regex
JDB ยังคงจำ Monica

3

อันนี้ใช้ได้กับฉัน:

(?P<value>[-+]*\d+\.\d+|[-+]*\d+)

คุณยังสามารถใช้อันนี้ (โดยไม่มีพารามิเตอร์ที่ตั้งชื่อ):

([-+]*\d+\.\d+|[-+]*\d+)

ใช้เครื่องทดสอบ regex ออนไลน์เพื่อทดสอบ (เช่น regex101)


2
^[+]?([0-9]{1,2})*[.,]([0-9]{1,1})?$

สิ่งนี้จะตรงกับ:

  1. 1.2
  2. 12.3
  3. 1,2
  4. 12,3

ขณะที่ข้อมูลโค้ดนี้คือการต้อนรับและอาจให้ความช่วยเหลือบางส่วนก็จะได้รับการปรับปรุงอย่างมากถ้ามันรวมถึงคำอธิบายของวิธีการและเหตุผลที่แก้ปัญหานี้ จำไว้ว่าคุณกำลังตอบคำถามสำหรับผู้อ่านในอนาคตไม่ใช่แค่คนที่ถามตอนนี้! โปรดแก้ไขคำตอบของคุณเพื่อเพิ่มคำอธิบายและระบุข้อ จำกัด และสมมติฐานที่ใช้
Toby Speight

โอ้ขอบคุณฉันกำลังตกหลุมรักสิ่งนี้
Serg Burlaka

0
[+-]?(([1-9][0-9]*)|(0))([.,][0-9]+)?

[+-]? - เครื่องหมายนำหน้า

(([1-9][0-9]*)|(0)) - จำนวนเต็มโดยไม่มีศูนย์นำหน้ารวมทั้งศูนย์เดียว

([.,][0-9]+)? - ส่วนเศษส่วนเสริม


1
ให้ข้อมูลเพิ่มเติม - สำหรับคนที่ไม่รู้จัก regexps มันคือ hyerogliphs สำหรับคนที่รู้จักพวกเขาพวกเขาไม่ต้องการมัน
peterh - คืนสถานะ Monica

0

ใน C ++ โดยใช้ไลบรารี regex

คำตอบจะเป็นดังนี้:

[0-9]?([0-9]*[.])?[0-9]+

สังเกตว่าฉันไม่ได้ใช้สัญลักษณ์ถ้าคุณต้องการให้มีสัญลักษณ์มันจะเป็นประมาณนี้:

[+-]?([0-9]*[.])?[0-9]+

นอกจากนี้ยังแยกตัวเลขปกติหรือเลขฐานสิบ


0

ในสัญกรณ์ c จำนวนลอยสามารถเกิดขึ้นได้ในรูปทรงต่อไปนี้:

  1. 123
  2. 123.
  3. 123.24
  4. .24
  5. 2e-2 = 2 * 10 ธาร -2 = 2 * 0.1
  6. 4E + 4 = 4 * 10 พาว 4 = 4 * 10,000

สำหรับการสร้าง float regular expresion ก่อนอื่นฉันจะสร้าง "int regular expresion variable":

(([1-9][0-9]*)|0) will be int

ตอนนี้ฉันจะเขียนส่วนเล็ก ๆ ของการขยายตัวอย่างปกติของโฟล - วิธีแก้ปัญหาคือการต่อชิ้นส่วนเหล่านั้นด้วยหรือซิมโบล "|"

ชิ้น:

- (([+-]?{int}) satysfies case 1
- (([+-]?{int})"."[0-9]*)  satysfies cases 2 and 3
- ("."[0-9]*) satysfies case 4
- ([+-]?{int}[eE][+-]?{int}) satysfies cases 5 and 6

วิธีแก้ปัญหาสุดท้าย (การต่อชิ้นส่วนเล็ก ๆ ):

(([+-]?{int})|(([+-]?{int})"."[0-9]*)|("."[0-9]*)|([+-]?{int}[eE][+-]?{int})


-1

สำหรับ javascript

const test = new RegExp('^[+]?([0-9]{0,})*[.]?([0-9]{0,2})?$','g');

ซึ่งจะใช้ได้กับ 1.23 1234.22 0 0.12 12

คุณสามารถเปลี่ยนส่วนใน{}เพื่อให้ได้ผลลัพธ์ที่แตกต่างกันในความยาวทศนิยมและด้านหน้าของทศนิยมเช่นกัน ใช้ในอินพุตสำหรับป้อนหมายเลขและตรวจสอบทุกอินพุตเมื่อคุณพิมพ์อนุญาตเฉพาะสิ่งที่ส่งผ่านเท่านั้น

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.