เพิ่มตัวเลขด้วย Regex


39

ฉันต้องการลองความท้าทายกอล์ฟ regex รูปแบบใหม่ซึ่งขอให้คุณแก้ปัญหาการคำนวณแบบไม่ย่อยโดยไม่มีอะไรนอกจากการทดแทน regex เพื่อให้เป็นไปได้มากขึ้นและน้อยลงของงานบ้านคุณจะได้รับอนุญาตให้ใช้การทดแทนหลายอย่างหนึ่งหลังจากที่อื่น

ความท้าทาย

เราจะเริ่มต้นง่าย: กำหนดสตริงที่มีจำนวนเต็มบวกสองจำนวนโดยที่ตัวเลขทศนิยมคั่นด้วย a ,สร้างสตริงที่มีผลรวมของพวกเขาเช่นเดียวกับเป็นทศนิยม ดังนั้นง่ายมาก

47,987

ควรเปลี่ยนเป็น

1034

คำตอบของคุณควรใช้กับจำนวนเต็มบวกโดยพลการ

รูปแบบ

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

Regex    Modifiers   Replacement   Repeat?
\b(\d)   g           |$1           No
|\d      <none>      1|            Yes
\D       g           <empty>       No

รับอินพุต123,456การส่งนี้จะประมวลผลอินพุตดังนี้: การทดแทนแรกจะถูกใช้เพียงครั้งเดียวและให้ผลลัพธ์:

|123,|456

ตอนนี้การทดแทนที่สองถูกนำไปใช้ในการวนซ้ำจนกว่าสตริงจะหยุดการเปลี่ยนแปลง

1|23,|456
11|3,|456
111|,|456
111|,1|56
111|,11|6
111|,111|

และสุดท้ายการทดแทนที่สามจะถูกนำมาใช้ครั้งเดียว:

111111

โปรดทราบว่าเกณฑ์การเลิกจ้างสำหรับลูปคือการเปลี่ยนแปลงสตริงหรือไม่ไม่ว่า regex จะพบการจับคู่หรือไม่ (นั่นคือมันอาจสิ้นสุดหากคุณพบคู่ที่ตรงกัน แต่การแทนที่นั้นเหมือนกับการแข่งขัน)

เกณฑ์การให้คะแนน

คะแนนหลักของคุณคือจำนวนขั้นตอนการเปลี่ยนตัวในการส่งของคุณ การทดแทนซ้ำทุกครั้งจะนับเป็น10ขั้น 1 + 10 + 1 = 12ดังนั้นตัวอย่างข้างต้นจะให้คะแนน

ในกรณีของการเสมอ (ไม่น่าจะเกินไป) คะแนนรองคือผลรวมของขนาดของทุกขั้นตอน สำหรับแต่ละขั้นตอนให้เพิ่ม regex ( ไม่มีตัวคั่น) ตัวดัดแปลงและสตริงการแทนที่ (6 + 1 + 3) + (3 + 0 + 2) + (2 + 1 + 0) = 18สำหรับตัวอย่างข้างต้นนี้จะเป็น

กฎเบ็ดเตล็ด

คุณสามารถใช้รสชาติของ regex ใดก็ได้ (ซึ่งคุณควรระบุ) แต่ทุกขั้นตอนต้องใช้รสชาติเดียวกัน นอกจากนี้คุณจะต้องไม่ใช้คุณสมบัติใด ๆ ของภาษาโฮสต์ของ flavour เช่น callbacks แทนหรือโมดิeฟายเออร์ของ Perl ซึ่งประเมินโค้ด Perl การจัดการทั้งหมดจะต้องเกิดขึ้นเฉพาะผ่านการทดแทน regex

โปรดทราบว่ามันขึ้นอยู่กับรสชาติและตัวดัดแปลงของคุณว่าการแทนที่แต่ละครั้งจะแทนที่การเกิดขึ้นทั้งหมดหรือเพียงครั้งเดียวเท่านั้น เช่นถ้าคุณเลือก ECMAScript รสขั้นตอนเดียวโดยค่าเริ่มต้นจะแทนที่เพียงหนึ่งครั้งเท่านั้นยกเว้นว่าคุณใช้gตัวแก้ไข ในทางตรงกันข้ามถ้าคุณใช้. NET รสแต่ละขั้นตอนจะแทนที่ทุกสิ่งที่เกิดขึ้น

สำหรับภาษาที่มีวิธีการทดแทนที่แตกต่างกันสำหรับการแทนที่แบบเดี่ยวและแบบโกลบอล (เช่น Ruby's subvs. gsub) ให้สมมติว่าการแทนที่แบบเดี่ยวเป็นค่าเริ่มต้นและจัดการการแทนที่แบบโกลบอลเช่นgตัวดัดแปลง

การทดสอบ

หากรสชาติที่คุณเลือกเป็น. NET หรือ ECMAScript คุณสามารถใช้Retinaเพื่อทดสอบการส่งของคุณ สำหรับรสชาติอื่น ๆ คุณอาจจะต้องเขียนโปรแกรมขนาดเล็กในภาษาโฮสต์ซึ่งใช้การทดแทนตามลำดับ หากคุณมีโปรดระบุโปรแกรมทดสอบนี้ในคำตอบของคุณ


หากใครมีความคิดที่ดีว่าจะเรียกความท้าทายประเภทนี้อย่างไรให้แสดงความคิดเห็น! :) (ในกรณีที่ฉันกำลังทำสิ่งเหล่านี้มากขึ้นในอนาคต)
Martin Ender

ผู้ที่ชอบสิ่งนี้อาจเพลิดเพลินกับการเพิ่มโดยไม่ต้องเพิ่มและทวีคูณโดยไม่มีตัวเลข
Toby Speight

"รสชาติ" ของเรจิน่าของเรจิน่าเป็นสิ่งที่ถูกต้องหรือไม่? : P (ผมค่อนข้างภูมิใจในตัวเองในการบริหารจัดการเพื่อเพิ่มตัวเลขสองตัวที่ทุกคนให้อยู่คนเดียวกอล์ฟมัน.)
totallyhuman

รสชาติของ @icrieverytim Retina เป็นเพียงรสชาติของ. NET
Martin Ender

แต่ Retina มีฟีเจอร์. NET ไม่ได้ใช่ไหม?
สิ้นเชิง

คำตอบ:


32

. NET รสคะแนน: 2

Regex        Modifiers  Replacement  Repeat?
<empty>      <none>     9876543210   No
<see below>  x          <empty>      No

ฉันยังไม่สนใจที่จะตีกอล์ฟและxเป็นเพียงการละเว้นช่องว่าง

ก่อนอื่นให้แทรก9876543210แต่ละตำแหน่งจากนั้นลบอักขระดั้งเดิมและอักขระที่ไม่ใช่ตัวเลขปัจจุบันของผลรวม

regex ใหญ่ (1346 ไบต์โดยไม่มีช่องว่างและความคิดเห็น):

# If the length of the left number <= right number, delete every digit on the left.
.(?=.*,(?<=^(?<len>.)*,)(?<-len>.)*(?(len)(?!)))|

# Do the opposite if it is not the case.
.(?<=(?(len)(?!))(?<-len>.)*(?=(?<len>.)*$),.*)|

# Remove leading zeros.
(?<=(^|,).{9})0|

# Delete everything that is not the current digit of the sum.
.(?!
    # For digits in the left part:
    (?<cur>.){0,9}               # cur = the matched digit
    (?=(.{11})*,)                # and find the position before the next digit.
    (?<first>)                   # first = true
    (                            # Loop on the less significant digits:
        (?<cur>){10}             # cur += 10
        (?<=                     # cur -= the current digit in this number.
            (
                0|^|
                1(?<-cur>)|
                2(?<-cur>){2}|
                3(?<-cur>){3}|
                4(?<-cur>){4}|
                5(?<-cur>){5}|
                6(?<-cur>){6}|
                7(?<-cur>){7}|
                8(?<-cur>){8}|
                9(?<-cur>){9}
            )
            .{10}
        )
        (?=
            (?<pos>.{11})*,      # pos = which digit it is.
            .*$(?<=              # cur -= the current digit in the other number.
                (
                    0|,|
                    1(?<-cur>)|
                    2(?<-cur>){2}|
                    3(?<-cur>){3}|
                    4(?<-cur>){4}|
                    5(?<-cur>){5}|
                    6(?<-cur>){6}|
                    7(?<-cur>){7}|
                    8(?<-cur>){8}|
                    9(?<-cur>){9}
                )
                .{10}
                (?(pos)(?!))     # Assert pos = 0.
                                 # Skip pos input digits from the end.
                                 # But stop and set pos = 0 if the comma is encountered.
                ((?<-pos>\d{11})|(?<=(?>(?<-pos>.)*),.{10}))*
            )
        )
        (?(first)                # If first:
            (?>((?<-cur>){10})?) #  cur -= 10 in case there is no carry.
                                 #  Assert cur = 0 or 1, and if cur = 1, set cur = 10 as carry.
            (?(cur)(?<-cur>)(?(cur)(?!))(?<cur>){10})
            (?<-first>)          #  first = false
        |                        # Else:
                                 #  cur is 10 or 20 at the beginning of an iteration.
                                 #  It must be 1 to 11 to make the equation satisfiable.
            (?<-cur>)            #  cur -= 1
            (?(cur)              #  If cur > 0:
                                 #   cur -= max(cur, 9)
                (?(cur)(?<-cur>)){9}
                (?(cur)          #   If cur > 0:
                                 #    Assert cur = 1 (was 11) and set cur = 10.
                    (?<-cur>)(?(cur)(?!))(?<cur>){10}
                |                #   Else:
                    .*(?=,)      #    cur was 2 to 10, break from the loop.
                )
            )                    #  Else cur is 0 (was 1) and do nothing.
        )
        (.{11}|,)                # Jump to the next digit.
    )*(?<=,)(?(cur)(?!))         # End the loop if it is the last digit, and assert cur = 0.
|
    # Do the same to the right part. So the sum will be calculated two times.
    # Both are truncated to the original length of the number on that side + 1.
    # Only the sum on the longer side will be preserved in the result.
    (?<cur>\d){0,9}
    (?=(\d{11})*$)
    (?<first>)
    (
        (?<cur>){10}
        (?<=
            (
                0|,|
                1(?<-cur>)|
                2(?<-cur>){2}|
                3(?<-cur>){3}|
                4(?<-cur>){4}|
                5(?<-cur>){5}|
                6(?<-cur>){6}|
                7(?<-cur>){7}|
                8(?<-cur>){8}|
                9(?<-cur>){9}
            )
            .{10}
        )
        (?=
            (?<pos>.{11})*$
            (?<=
                (
                    0|^|
                    1(?<-cur>)|
                    2(?<-cur>){2}|
                    3(?<-cur>){3}|
                    4(?<-cur>){4}|
                    5(?<-cur>){5}|
                    6(?<-cur>){6}|
                    7(?<-cur>){7}|
                    8(?<-cur>){8}|
                    9(?<-cur>){9}
                )
                .{10}
                (?(pos)(?!))
                ((?<-pos>\d{11})|(?<=^.{10})(?=(?>(?<-pos>.)*)))*
                ,.*
            )
        )
        (?(first)
            (?>((?<-cur>){10})?)
            (?(cur)(?<-cur>)(?(cur)(?!))(?<cur>){10})
            (?<-first>)
        |
            (?<-cur>)
            (?(cur)
                (?(cur)(?<-cur>)){9}
                (?(cur)
                    (?<-cur>)(?(cur)(?!))(?<cur>){10}
                |
                    .*$(?<end>)
                )
            )
        )
        (.{11}|$(?<end>))
    )*(?<-end>)(?(cur)(?!))
)

สิ่งนี้ทำให้ฉันคิดถึงระดับสุดท้ายของ Manufactoria ... แต่ฉันคิดว่า. NET regex ซึ่งเห็นได้ชัดว่าไม่ใช่ "ปกติ" อีกต่อไปสามารถแก้ปัญหาใด ๆ ใน PH และนี่เป็นเพียงอัลกอริทึมใน L


4
hail .NET กลุ่มสมดุลทั้งหมด
Sp3000

ก่อนอื่นฉันคิดว่ากระบวนการห้าขั้นตอนของฉันค่อนข้างดี จากนั้นฉันเห็นมีคนอ้างสิทธิ์แก้ปัญหาด้วยความยาวครึ่งหนึ่ง ถ้าอย่างนั้น ... สิ่งนี้นับเป็น regex หรือไม่
John Dvorak

1
@JanDvorak สำหรับทฤษฎี "การแสดงออกปกติ", ไม่ สำหรับ "regex" ใช่ทุกคนเรียกสิ่งนี้ว่า regex และเกือบทุกรสชาติของ regex จะมีลักษณะเช่นนี้ Microsoft ยังคงเรียกพวกเขาว่า " นิพจน์ปกติ " อย่างเป็นทางการ
jimmy23013

ว้าวนี่เป็นงานที่น่าทึ่ง!
user230910

6

คะแนน: 24

ฉันคิดว่ามันใช้งานได้ ...

Regex                                                                                                                       Modifiers   Replacement             Repeat?
(?|(\d*)(\d)(,\d*)(\d)|(^,?\d*)(\d)|, |^,)                                                                                  <none>      $1$3 $2$4               Yes
$                                                                                                                           <none>      ;111111111234567890     No
0|(?|(;.*)|9(?=.*(1{9}))|8(?=.*(1{8}))|7(?=.*(1{7}))|6(?=.*(1{6}))|5(?=.*(1{5}))|4(?=.*(1{4}))|3(?=.*(111))|2(?=.*(11)))    g           $1                      No
 1{10}                                                                                                                      <none>      1                       Yes
 (?|1{9}(?=.*(9))|1{8}(?=.*(8))|1{7}(?=.*(7))|1{6}(?=.*(6))|1{5}(?=.*(5))|1{4}(?=.*(4))|1{3}(?=.*(3))|1{2}(?=.*(2))|)       g            $1                     No
 (?!\d)(?=.*(0))| |;.*                                                                                                      g           $1                      No

ฉันยังไม่ได้ใช้เวลามากมายในการเล่นกอล์ฟในการแสดงออกปกติของแต่ละบุคคล ฉันจะพยายามโพสต์คำอธิบายในเร็ว ๆ นี้ แต่ตอนนี้จะสาย ในระหว่างนี้นี่คือผลลัพธ์ระหว่างแต่ละขั้นตอน:

'47,987'
' 9 48 77'
' 9 48 77;111111111234567890'
' 111111111 111111111111 11111111111111;111111111234567890'
'1  111 1111;111111111234567890'
'1  3 4;111111111234567890'
'1034'

โปรแกรม perl เต็มรูปแบบ:

$_ = <>;
chomp;

do {
    $old = $_;
    s/(?|(\d*)(\d)(,\d*)(\d)|(^,?\d*)(\d)|, |^,)/$1$3 $2$4/;
} while ($old ne $_);

s/$/;111111111234567890/;

s/0|(?|(;.*)|9(?=.*(1{9}))|8(?=.*(1{8}))|7(?=.*(1{7}))|6(?=.*(1{6}))|5(?=.*(1{5}))|4(?=.*(1{4}))|3(?=.*(111))|2(?=.*(11)))/$1/g;

do {
    $old = $_;
    s/ 1{10}/1 /;
} while ($old ne $_);

s/ (?|1{9}(?=.*(9))|1{8}(?=.*(8))|1{7}(?=.*(7))|1{6}(?=.*(6))|1{5}(?=.*(5))|1{4}(?=.*(4))|1{3}(?=.*(3))|1{2}(?=.*(2))|)/ $1/g;

s/ (?!\d)(?=.*(0))| |;.*/$1/g;

print "$_\n";

ดูเหมือนว่าเป็นหลักฐานของแนวคิดของฉันเอง :) ฉันมีการแทนที่ไม่ใช่แบบวน 7 ครั้ง แต่ฉันไม่ได้พยายามอย่างยิ่งที่จะทำให้พวกเขาผิดหวัง
Martin Ender

@ MartinBüttnerฮ่าฮ่าดี! ผมค่อนข้างมั่นใจว่าผู้ใต้บังคับบัญชาสองครั้งสุดท้ายของฉันอาจจะรวมเช่นกัน แต่ฉันเคยพอวันหนึ่ง ...
GRC

ช่องว่างชั้นนำทั้งหมดโดยเจตนา?
เครื่องมือเพิ่มประสิทธิภาพ

@Optimizer ใช่ ฉันควรจะเลือกตัวละครที่ดีกว่าขออภัย
grc

5

ทุกรส regex, 41

    s/0/d/g
    ...
    s/9/dxxxxxxxxx/g
rep s/xd/dxxxxxxxxxxx/g
    s/[d,]//g
rep s/(^|d)xxxxxxxxxx/xd/g
    s/(^|d)xxxxxxxxx/9/g
    ...
    s/(^|d)x/1/g
    s/d/0/g

ลอง unary กัน dทำหน้าที่เป็นตัวคั่นคำสั่งซื้อหลักxเก็บค่า อันดับแรกเราแยกแต่ละหลักแล้วบีบ x10 ตัวคูณไปทางซ้ายแล้วปล่อยตัวแยกทั้งหมดแล้วใส่กลับตัวคูณแล้วแปลงแต่ละคำสั่งกลับเป็นตัวเลข


5

.NET Regex, 14

ไม่ดีเท่าโซลูชันของผู้ใช้ 23013 แต่มันก็สนุกดี ไม่มีการเปลี่ยนใด ๆ ที่มีตัวดัดแปลง

เหตุผลสำหรับ. regex NET นั้นไม่ได้เกิดจากการสร้างสมดุลให้กับกลุ่มเพียงครั้งเดียว - ฉันเพิ่งทดสอบกับRetinaซึ่งใช้. NET และฉันก็พบว่าความยาวที่หลากหลายของตัวแปรช่วยได้มาก

เปลี่ยน 1 (ทำซ้ำ = ไม่)

regex:

\d(?=\d+$)|\d(?=\d+,)|\d(?=,(\d+)$)|(?<=(\d+),\d*)\d$

การแทนที่

0$1$2

สลับตัวเลขทั้งสองโดยเติมเต็มเพื่อให้มีเลขศูนย์นำหน้าเท่ากัน

เปลี่ยน 2 (เล่นซ้ำ = ไม่)

regex:

(\d+)

เปลี่ยน:

 $1

เพิ่มช่องว่างหน้าตัวเลขแต่ละตัว

เปลี่ยน 3 (เล่นซ้ำ = ไม่)

$

เปลี่ยน:

&0 ~00000 ~00101 ~00202 ~00303 ~00404 ~00505 ~00606 ~00707 ~00808 ~00909 ~01001 ~01102 ~01203 ~01304 ~01405 ~01506 ~01607 ~01708 ~01809 ~01910 ~02002 ~02103 ~02204 ~02305 ~02406 ~02507 ~02608 ~02709 ~02810 ~02911 ~03003 ~03104 ~03205 ~03306 ~03407 ~03508 ~03609 ~03710 ~03811 ~03912 ~04004 ~04105 ~04206 ~04307 ~04408 ~04509 ~04610 ~04711 ~04812 ~04913 ~05005 ~05106 ~05207 ~05308 ~05409 ~05510 ~05611 ~05712 ~05813 ~05914 ~06006 ~06107 ~06208 ~06309 ~06410 ~06511 ~06612 ~06713 ~06814 ~06915 ~07007 ~07108 ~07209 ~07310 ~07411 ~07512 ~07613 ~07714 ~07815 ~07916 ~08008 ~08109 ~08210 ~08311 ~08412 ~08513 ~08614 ~08715 ~08816 ~08917 ~09009 ~09110 ~09211 ~09312 ~09413 ~09514 ~09615 ~09716 ~09817 ~09918 ~10001 ~10102 ~10203 ~10304 ~10405 ~10506 ~10607 ~10708 ~10809 ~10910 ~11002 ~11103 ~11204 ~11305 ~11406 ~11507 ~11608 ~11709 ~11810 ~11911 ~12003 ~12104 ~12205 ~12306 ~12407 ~12508 ~12609 ~12710 ~12811 ~12912 ~13004 ~13105 ~13206 ~13307 ~13408 ~13509 ~13610 ~13711 ~13812 ~13913 ~14005 ~14106 ~14207 ~14308 ~14409 ~14510 ~14611 ~14712 ~14813 ~14914 ~15006 ~15107 ~15208 ~15309 ~15410 ~15511 ~15612 ~15713 ~15814 ~15915 ~16007 ~16108 ~16209 ~16310 ~16411 ~16512 ~16613 ~16714 ~16815 ~16916 ~17008 ~17109 ~17210 ~17311 ~17412 ~17513 ~17614 ~17715 ~17816 ~17917 ~18009 ~18110 ~18211 ~18312 ~18413 ~18514 ~18615 ~18716 ~18817 ~18918 ~19010 ~19111 ~19212 ~19313 ~19414 ~19515 ~19616 ~19717 ~19818 ~19919

เพิ่มบิตพกพา (คน&0) <c> <a> <b> <carry of a+b+c> <last digit of a+b+c>เช่นเดียวกับตารางการค้นหายักษ์ใหญ่ของ

เปลี่ยน 4 (ทำซ้ำ = ใช่)

regex:

(?<=(\d),.*(\d)&)(\d)(?=.*~\3\1\2(.))|(\d)(?=,.*\d&)|(?<=\d,.*)(\d)(?=&)|^(?=.* .*(\d),.*(\d)&(\d).*~\9\7\8.(.))

เปลี่ยน:

$4$10

จดเลขตัวสุดท้ายของแต่ละตัวเลขไว้และหา (ผลรวมนำไป) ใส่ผลรวมที่จุดเริ่มต้นของสตริงและแทนที่การพกพา

เปลี่ยน 5 (เล่นซ้ำ = ไม่)

regex:

^0*| .*

เปลี่ยน:

<empty>

ทำความสะอาด.

ตัวอย่างการวิ่ง

Repl no.        String
(input)         1428,57
1               000057,001428
2                000057, 001428
3                000057, 001428&0 <lookup table>
4               5 00005, 00142&1 <lookup table>
4               85 0000, 0014&0 <lookup table>
4               485 000, 001&0 <lookup table>
4               1485 00, 00&0 <lookup table>
4               01485 0, 0&0 <lookup table>
4               001485 , &0 <lookup table>
5               1485

(โดยการรวมขั้นตอนบางอย่างเข้าด้วยกันฉันจะได้ 12 แต่เนื่องจากมันยุ่งมากและไม่ชนะเลยฉันคิดว่าฉันจะรักษาเวอร์ชั่นที่หรูหรากว่านี้ไว้แทน)


4

คะแนน: 50 40 31 21

ขอบคุณสำหรับความท้าทายที่ยอดเยี่ยมนี้ โซลูชันนี้ไม่หรูหรามาก แต่ด้วยข้อ จำกัด ฉันไม่เห็นวิธีจัดการกับตัวเลขโดยทั่วไปในผลลัพธ์

โซลูชันนี้มีกลุ่มการดักจับที่บางครั้งไม่ตรงกันและต้องพึ่งพากลุ่มที่ว่างเปล่าเมื่อเกิดขึ้น ใช้งานได้ใน Perl แม้ว่าโดยปกติจะสร้างคำเตือน

Regex 1:     (((((((((9)|8)|7)|6)|5)|4)|3)|2)|1)|0                                            
Modifiers:   g
Replacement: <$1$2$3$4$5$6$7$8$9>             
Repeat:      no

Regex 2:     (.*)<(\d*)>(,.*)<(\d*)>|(.*)<(\d*)>(.*)|(?:(^[^<]*)b(\d*)c)?(b)\d{9}(\d)(\d*)(c)
Modifiers:   none 
Replacement: \8\1\5\3b$9$11\2\6\4c\7$10$12$13 
Repeat:      yes

Regexes 3-12: ,?baaaaaaaaac
Modifiers:    g
Replacement:  9 etc. (one for each digit)

ตัวอย่างโค้ด Perl แบบเต็มพร้อมคำอธิบายและการพิมพ์ผลลัพธ์ระดับกลาง:

no warnings;
use 5.16.0;

$_ = '47,987';

#Convert numbers to beans
s/(((((((((9)|8)|7)|6)|5)|4)|3)|2)|1)|0/<$1$2$3$4$5$6$7$8$9>/g;

say;
my $last;

#Combine pairs of digits, starting with least significant.
do {
    $last=$_;
    s/(.*)<(\d*)>(,.*)<(\d*)>|(.*)<(\d*)>(.*)|(?:(^[^<]*)b(\d*)c)?(b)\d{9}(\d)(\d*)(c)/\8\1\5\3b$9$11\2\6\4c\7$10$12$13/;
    say;
}
while ($last ne $_);

#Convert beans back to numbers.
s/,?b\d{9}c/9/g;
s/,?b\d{8}c/8/g;
s/,?b\d{7}c/7/g;
s/,?b\d{6}c/6/g;
s/,?b\d{5}c/5/g;
s/,?b\d{4}c/4/g;
s/,?b\d{3}c/3/g;
s/,?b\d{2}c/2/g;
s/,?b\d{1}c/1/g;
s/,?bc/0/g;

say;

อัปเดต: ฉันสามารถรวมการวนรอบสองวนเข้าด้วยกันโดยประหยัด 10

อัปเดต 2: ฉันจัดการเพื่อถอดรหัสการแปลงตัวเลขอินพุทด้วย regex เดียว

อัปเดต 3: ฉันลดเหลือ Regex ลูปเดียว


ทางออกที่น่าสนใจ :) วงเล็บปีกกาทำอะไรในสตริงการแทนที่? คือ${1}แตกต่างจาก$1? นอกจากนี้คุณอาจต้องการรวมจำนวนไบต์ในกรณีที่มีความสัมพันธ์
Martin Ender

@ MartinBüttnerเครื่องมือจัดฟันแยกชื่อตัวแปรออกจากอักขระอื่น ๆ ที่อาจเป็นตัวแปรได้อย่างง่ายดาย

อ่านั่นสมเหตุสมผลแล้ว ขอบคุณ
Martin Ender

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