【发布时间】:2014-04-14 11:35:00
【问题描述】:
我面临一个挑战,以匹配以下格式的输入:
- 输入由键=值对组成。键以斜线开头。该值可以是数字或引号中的字符串。
- 该值可以选择包含转义引号,即引号后跟引号 ("")。这种转义的报价应被视为价值的一部分。无需检查转义引号是否平衡(例如,以另一个转义引号结尾)。
正则表达式应匹配序列中给定的 key=value 部分,并且不应因长输入而中断(例如,值是 10000 个字符)。
首先我想到了这个解决方案:
/(\w+)=(\d+|"(?:""|[^"])+"(?!"))
它的表现还不错,但是它在 Java6 中失败并出现 StackOverflowError 的长输入(例如现金 regexplanet)。我尝试对其进行改进以更快地运行:
/(\w+)=(\d+|"(?:""|[^"]+)+"(?!"))
但是如果输入不匹配,它会在回溯中进入无限循环尝试匹配它。
然后我来到了这个正则表达式:
/(\w+)=(\d+|".+?(?<!")(?:"")*"(?!"))
执行速度较慢,但似乎可以解决任务。
谁能推荐一个更好/更快的正则表达式?
示例输入:
/mol_type="protein" /transl_table=11 /note="[CDS] (""multi
line)" nn /organism="""Some"" Sequence" nn /organism="Some ""Sequence"""
/translation="MHPSSSRIPHIAVVGVSAIFPGSLDAHGFWRDILSGTDLITDVPSTHWLVE
DYYDPDPSAPDKTYAKRGAFLKDVPFDPLEWGVPPSIVPATDTTQLLALIVAKRVLEDAAQGQFE
SMSRERMSVILGVTSAQELLASMVSRIQRPVWAKALRDLGYPEDEVKRACDKIAGNYVPWQESSF
PGLLGNVVAGRIANRLDLGGTNCVTDAACASSLSAMSMAINELALGQSDLVIAGGCDTMNDAFMY
MCFSKTPALSKSGDCRPFSDKADGTLLGEGIAMVALKRLDDAERDGDRVYAVIRGIGSSSDGRSK
SVYAPVPEGQAKALRRTYAAAGYGPETVELMEAHGTGTKAGDAAEFEGLRAMFDESGREDRQWCA
LGSVKSQIGHTKAAAGAAGLFKAIMALHHKVLPPTIKVDKPNPKLDIEKTAFYLNTQARPWIRPG
DHPRRASVSSFGFGGSNFHVALEEYTGPAPKAWRVRALPAELFLLSADTPAALADRARALAKEAE
VPEILRFLARESVLSFDASRPARLGLCATDEADLRKKLEQVAAHLEARPEQALSAPLVHCASGEA
PGRVAFLFPGQGSQYVGMGADALMTFDPARAAWDAAAGVAIADAPLHEVVFPRPVFSDEDRAAQE
ARLRETRWAQPAIGATSLAHLALLAALGVRAEAFAGHSFGEITALHAAGALSAADLLRVARRRGE
LRTLGQVVDHLRASLPAAGPAASASPAAAASVPKASTAAVPAVASVAAPGAAEVERVVMAVVAET
TGYPAEMLGLQMELESDLGIDSIKRVEILSAVRDRTPGLSEVDASALAQLRTLGQVVDHLRASLP
AASAGPAVAAPAAKAPAVAAPTGVSGATPGAAEVERVVMAVVAETTGYPAEMLGLQMELESDLGI
DSIKRVEILSAVRDRTPGLAEVDASALAQLRTLGQVVDHLRASLGPAAVTAGAAPAEPAEEPAST
PLGRWTLVEEPAPAAGLAMPGLFDAGTLVITGHDAIGPALVAALAARGIAAEYAPAVPRGARGAV
FLGGLRELATADAALAVHREAFLAAQAIAAKPALFVTVQDTGGDFGLAGSDRAWVGGLPGLVKTA
ALEWPEASCRAIDLERAGRSDGELAEAIASELLSGGVELEIGLRADGRRTTPRSVRQDAQPGPLP
LGPSDVVVASGGARGVTAATLIALARASHARFALLGRTALEDEPAACRGADGEAALKAALVKAAT
SAGQRVTPAEIGRSVAKILANREVRATLDAIRAAGGEALYVPVDVNDARAVAAALDGVRGALGPV
TAIVHGAGVLADKLVAEKTVEQFERVFSTKVDGLRALLGATAGDPLKAIVLFSSIAARGGNKGQC
DYAMANEVLNKVAAAEAARRPGCRVKSLGWGPWQGGMVNAALEAHFAQLGVPLIPLAAGAKMLLD
ELCDASGDRGARGQGGAPPGAVELVLGAEPKALAAQGHGGRVALAVRADRATHPYLGDHAINGVP
VVPVVIALEWFARAARACRPDLVVTELRDVRVLRGIKLAAYESGGEVFRVDCREVSNGHGAVLAA
ELRGPQGALHYAATIQMQQPEGRVAPKGPAAPELGPWPAGGELYDGRTLFHGRDFQVIRRLDGVS
RDGIAGTVVGLREAGWVAQPWKTDPAALDGGLQLATLWTQHVLGGAALPMSVGALHTFAEGPSDG
PLRAVVRGQIVARDRTKADIAFVDDRGSLVAELRDVQYVLRPDTARGQA"
/note="primer of Streptococcus pneumoniae
预期输出(来自regexhero.net):
【问题讨论】:
-
看看here...
-
String.split和朋友呢(很可能不会拆分,因为可以转义分隔符)?我很确定大多数 JSON 解析器不是基于正则表达式的。 -
@fge:感谢您的链接。确实是类似的问题,但我不需要检查转义引号是否平衡,因此模板
E(S|E)*对我来说不是最佳选择。 -
@zapl:拆分可能是一个好朋友——欢迎您发布您的想法作为答案。请注意,输入字符串可能在“key=value”部分之间包含一些“垃圾”文本(例如示例中的
nn),这是使用正则表达式解决问题的主要原因。