这篇文章最初于2014年7月8日发布为“你应该永远不会编码的七件事”。它于2019年3月12日更新并扩展。
作为程序员,我们喜欢解决问题。我们喜欢它的想法春天从我们的头部春天,穿过我们的指尖来创造神奇的解决方案。亚博直播平台
但有时,为了解决问题,我们可能过早地开始编写代码。我们可能会立即卷起袖子投入其中——从不考虑是否有人已经解决了类似的问题,并发布了已经编写、测试和调试过的代码。
有时候,我们需要停下来想一想,然后再开始打字。
例如,这九个通常遇到的编码问题几乎总是使用现有解决方案更好地解决,而不是尝试编写自己的代码:
1.解析HTML或XML
基于编码器的次数询问Stackoverflow上的这个主题许多人显然低估了解析HTML或XML的复杂性。从任意HTML中提取数据看似简单,但实际上这是一项应该留给库的工作。
假设您希望从中提取一个URLsrc
属性的一个< img >
标签:
最快的解决方案是使用一个简单的正则表达式(regex)和一个捕获来匹配模式:
/ /
字符串foo.jpg
将在捕获组#1中,可以分配给a
字符串。但是,如果标签有其他属性怎么办?
< img id = "棒" src = " foo.jpg”>
它会处理备用引号吗?
< img src = ' foo.jpg ' >
还是没有引用?
如果标签跨越多条线,那么是常何种方式?
你的代码知道忽略这个注释掉的标签吗?
< !——关于stackoverflow的常见问题涉及从Web API从JSON文件中提取数据的有人好奇的人。例如,“我怎样才能才能只得到麦克亨利电话号码?”{“姓名”:“Tacos El Norte”,“标签”:[“Tacos”,“墨西哥”,“电话”:{“MCHENRY”:“815-759-9227”,“Libertyville”:“847-837-3488“,”Waukegan“:”847-263-9001“}}在这种情况下,正常表达式不会起作用,因为JSON是结构化的,并且您无法轻易地用简单的正则表达式解析数据。您不能只搜索“MCHENRY”并采取任何遵循的内容,因为“MCHENRY”可能出现在多个领域。
另一个复杂因素是您可以将JSON倒入多行。正如多行标签可能导致从XML和HTML的数据带有正则表达式时造成问题,您可能对JSON具有相同的问题。
如果您在命令行中使用JSON,有一个非常有用的工具叫做JQ.为您解释和重新格式化JSON。
将我们的JSON文件传递给jq立即为我们格式化它:
金桥美元。炸玉米饼。json {"name": "Tacos El Norte", "tags": ["Tacos", "Mexican"], "phone": {"McHenry": "815-759-9227", "Libertyville": "847-837-3488", "Waukegan": "847-263-9001"}}然后,我们可以使用简单的查询来仅显示电话号码部分
数据结构:
$ JQ.phone Tacos.json {“MCHENRY”:“Libertyville”:“847-837-3488”,“Waukegan”:“847-263-9001”}然后只是一个电话号码:
$ JQ.PHONE.PHONE.MCHENRY TACOS.JSON“815-759-9227”对于从命令行提取数据来说,这是没问题的,但大多数情况下,您将使用编程语言。幸运的是,JSON是如此普遍,以至于每种编程语言都至少有一个库或模块来解析它。例如,在Python中,你可以这样写:
import json restaurant = json.load(open('tacos.json')) print(restaurant['phone']['McHenry'])在PHP中,你会写:
$ restaurant = json_decode(file_get_contents('tacos.json'));打印$ Restaurant-> Phone-> MCHENRY;使用您可以使用这么多工具,从JSON中提取数据所需的代码是您不需要写自己的代码。
4.电子邮件地址验证
有两种方法可以验证电子邮件地址:您可以通过简单的检查来实现,也可以根据规则验证RFC 2822.。
假设您想要一个简单的检查,验证电子邮件地址是否具有非空白字符,@符号,然后是更多的非空白字符。您可以使用此正则表达式:
/ ^ \ s + @ \ s + $ /这个正则表达式是不完整的,它允许无效的东西通过,但至少它会确认@符号在中间的存在。
您还可以对RFC 2822中的规则验证电子邮件地址,该规则定义了电子邮件地址的标准格式。这些规则比您实现的更复杂。即使您知道RFC中的所有规则,简单的正则表达式也不会进行这项工作。您需要使用解释和正确应用规则的库。
如果你是不是将全部验证RFC 2822,然后您至少可以验证规则的合理子集。这是许多情况下有效的设计权衡,但不要欺骗自己认为您已经涵盖了所有案例,除非您返回完整的RFC,或者使用由拥有的人写的图书馆使用。
5.处理URL.
URL与电子邮件地址几乎是可恶的,但它们仍然充满了您必须记住的令人讨厌的规则:您需要编码哪些字符?你如何处理空间?你用+迹象做什么?#sign后的字符有效了?
无论使用哪种语言,您都可以找到可以将url分解为所需组件的库,然后将它们重新组合,并进行正确的格式设置。您还将找到可以验证url的代码。
说你有网址:
https://beta.example.com:8000/r/example.为了只提取主机名,您可能会使用regex,或者使用您语言的标准函数。例如,使用PHP的内置
parse_url.
功能:$ url = https://beta.example.com: 8000 / r /例子的;$host = parse_url($url, PHP_URL_HOST);每种语言都有URL操作函数。使用它们。
6.日期/时间操作
起初,围绕日期/时间操纵的所有规则似乎容易包装。但事情很快就会变得复杂;您可能必须考虑多个时区,夏令时,闰年,甚至闰秒。例如,您可能必须弄清楚当前日期后10天或计算两次之间的分钟数。
在与美国时区交易时,这很难。在全球工作时,它会变得更加复杂。(你知道吗有些时区与相邻的时区相差几分钟,不是全部?)
即使是验证日期的简单也可能有角落案例。这不仅仅是“九月三十天......”的问题,以弄清楚一个月有多少天。你知道2000年是2月29日的闰年,但2100年不会是闰年吗?
为什么当现有库已经为您完成了它时,为什么会追踪所有这些变量?无论您是执行日期算术要计算日历上的特定时间,还是您验证输入字符串实际上是有效日期,请使用现有库。
7.模板系统
创建样板文本几乎是程序员的必经之路:
亲爱的#用户#,谢谢您对#product#的兴趣#...您的第一个版本的模板,如此可以工作一段时间。但是,您必须添加多种输出格式和数字格式,然后您必须在表中输出结构化数据,然后在和on-to-tehinal中输出结构,您建立了一个需要无尽的护理和喂养的ad hoc怪物。
如果您正在进行比简单的字符串字符串替换更复杂,请退后并找到一个好的模板库。为了使事情更加简单,如果您在PHP中编写,语言本身就是模板系统(尽管这通常不是它的主要用例)。
8.记录框架
在许多情况下,伐木工具开始小并成长为庞然大物。您编写了一个简单的函数来记录文件,但是您必须修改它,以便它可以记录到多个文件,或在完成时发送电子邮件通知,或者具有不同的日志级别,或者依此类推。
幸运的是,大多数语言至少有三个日志套餐已经存在,并且不会拯救你的恶化结束。开发的一个次要标准是
log4(langageName)
公约。早在2001年,发布了一个名为log4j的Java日志库。它开始流行,并被改编成其他语言。现在有一些库,比如log4php、log4py和log4go(分别用于PHP、Python和Go)。如果您正在寻找一个日志框架,可以从搜索开始log4(langageName)
。9.安全与加密
在案件中,我们向前看,我推荐使用现有代码来拯救自己的时间和麻烦。然而,在安全性和加密代码的情况下,还有一个更重要的原因:你不太可能自己做对。
根据施奈尔的法律,“任何人都可以发明一个加密算法,他们自己不能破裂;发明一个没有其他人可以破裂的更难更难。”通过比您更好的专家测试并攻击加密算法并攻击。(有关为什么要重用现有代码的安全性和加密的更多示例,请参阅“我们为什么不自己卷呢“在安全堆栈交换中。)
无论您是使用数据库绑定变量,避免在创建哈希时SQL注入或腌制密码,这是关键的不采取快捷方式。遵循推荐的实践。即使你认为你的方式和那么好,也可能不是。相信专业人士:将安全性和加密留给专家,并做他们所说的。
这不是矫枉过正吗?
有时,程序员不想使用现有的代码。我们为自己的技能感到自豪,我们喜欢编写代码来解决问题的过程。这很好,但通常解决问题的最佳方法是编写尽可能少的代码。在软件领域,最昂贵的时间是程序员的时间。在软件中包含一个额外的库可能会增加几毫秒的程序执行时间,而没有人会注意到这一点。值得注意的是,您花费了数小时或数天的时间从您编写的代码中寻找错误——但不需要这样做。