我不是问在哪里学习。我在网上找到了很多很好的资源,还有书籍等。
但是,我该如何解决这些问题。起点在哪里,终点在哪里?regexp处理器何时在文本上前进,何时保持立场并尝试其他匹配?等等
我想尝试找出埃及金字塔上的象形文字。
我不是问在哪里学习。我在网上找到了很多很好的资源,还有书籍等。
但是,我该如何解决这些问题。起点在哪里,终点在哪里?regexp处理器何时在文本上前进,何时保持立场并尝试其他匹配?等等
我想尝试找出埃及金字塔上的象形文字。
Answers:
我认为自动机理论的知识对于理解至关重要。
一旦了解了自动机是什么,以及如何定义正则语言,了解正则表达式将变得更加容易。
至于具体的语法和各种实现之间的区别……好吧,您只需要记住一些事情。也有帮助。
编辑
以下一些评论提出了重要观点:
不要忘记,正则表达式(在大多数编程语言中已实现)是自动机理论中正则表达式的超集。虽然良好的理论背景是一个有用的起点,但它并不能告诉您所有信息。(谢谢David Thornley)
多个评论者说,无需学习理论基础就可以学习各种正则表达式语法。虽然确实可以在不完全了解语法工作原理的情况下学习语法,但我的印象是,对语法的充分理解才是OP所追求的。问题是关于实际基础的:处理器何时升级?什么时候停止?如何确定其匹配项?那是基础,那是理论,它是基于自动机理论的。当然,您可以在不知道发动机工作原理的情况下驾驶汽车。但是如果您被问到“气体实际上是如何驱动的”-您必须谈论发动机的构造,不是吗?
通过练习。
我通过玩网络抓取而学到的。我敢肯定,我并不是一个人只是为了好玩而已。
一个示例:编写一些代码,从您最喜欢的体育网站上检索最新的足球,网球(实际上是您喜欢的运动)得分。通过编写一些代码来加载页面,使用正则表达式提取分数并将其输出到控制台或某些文本文件来完成此操作。确保使用选择的正则表达式仅检索分数,而没有其他内容。有时,这可能是非常具有挑战性的:-)
第二个示例:编写一些代码来检索您喜欢的网络漫画的图片(例如,我非常喜欢Sinfest)并将其存储在硬盘上的某个位置。仅使用正则表达式检索“ img”标记及其内容。如果标题存储在某个地方,也可以选择检索其标题。
我知道您不是在请求资源,而是Jeffrey EF Friedl的Mastering Regular Expressions(掌握正则表达式)是我学习它们如何工作以及如何使用它们的方法。甚至在使用了很多语法分析不同事物的意义之后,第一章对我来说还是新事物。
您想了解那些该死的正则表达式吗?读这本书。
起点在哪里,终点在哪里?regexp处理器何时在文本上前进,何时保持立场并尝试其他匹配?等等
我首先要澄清您的目标,然后弄清楚您的学习风格。
我对您的问题感到震惊的是,您问“我如何学习正则表达式?” 然后立即提出“正则表达式引擎如何在内部工作”的问题。您似乎在暗示这两件事是相互关联的,这很明显。也许您是一个通过分解或自己构建来学习事物工作方式的人。
对于初学者应用程序,通常无需了解工具的工作方式即可有效地使用它。您无需知道钻孔电机如何在木头上打孔;你需要了解如何使用钻,而不是如何建立一个钻。
那你的目标是什么?您是否打算学习如何构建正则表达式引擎?或者您打算学习如何有效使用正则表达式解决业务问题? 实现这些不同的目标可能需要不同的学习技巧。
要解决有关正则表达式引擎如何工作的特定问题:这取决于。正则表达式的“经典”理论方法是将正则表达式用作非确定性有限自动机的蓝图,然后构建等效的确定性有限自动机,然后对输入执行该自动机。
实际上,出于以下几个原因,几乎没有人这样做。首先,将状态数乘以可能的输入字符数将得出一个状态转换表,即使对于小的正则表达式来说也是如此。当然,大多数可以压缩,但是仍然有很多过渡规则。其次,其他方法通常更快。第三,所谓的“正则”表达式在现代的regexp库中不存在。它们根本不是普通语言。它们通常被下推自动机而非有限自动机语言识别。
(我开始写一长篇有关这些东西如何工作的系列文章,但是仅在前十二篇文章之后我就筋疲力尽了。如果您想对基本正则表达式的理论背景做一个简短的入门,可能会发现它们很有趣。)
实际的正则表达式引擎通常使用回溯策略。十多年前,我们为JScript引擎构建的正则表达式引擎现在将正则表达式编译为字节码语言,其中包括用于识别序列和回溯到较早状态的原语。然后,我们为该字节码语言构建了一个解释器。
在了解如何使用正则表达式之前,我不会尝试了解正则表达式引擎的工作原理。在开始研究各种不同引擎的优化策略之前,请先集中精力。
"[0-9]{3}"
可以匹配任意三位数字的正则表达式,而三位数字480是正则表达式的一个示例匹配的表达式。
我该如何应对?
像任何新事物一样:
10 Study
20 Practice
30 goto 10
我发现,大多数成功的老师首先会提供一些背景知识,从而开始教授任何学科。了解您正在学习的内容以及最重要的是为什么要学习它是很重要的。
正则表达式是匹配文本模式的一种方式。它本身是一种声明性语言,已集成到许多其他编程语言中。
我想强调,这是一个说明性语言,正则表达式表达有用的东西来匹配字符串,但他们不以任何方式表达怎样的计划是去这样做的匹配。因此,只需使用不同的RegEx解析器,就可以在同一编程语言中非常快速和非常慢地使用正则表达式。
创建正则表达式的原因与大多数编程语言的创建相同:程序员发现自己一遍又一遍地执行相同的复杂任务,并决定他们想要一种更简单的代码编写方式。
有些人会(并且应该)抱怨我的前一句话,其方式如下:
这是真的
RegEx 不会使程序变得更简单,RegEx会使程序的编写变得更简单。您仍需要在测试中进行彻底检查,以确保所有正确的案例均正确匹配,而所有错误的案例均未匹配。测试“全部”真的很困难,而使用复杂的模式,测试“大多数”真的很困难。最糟糕的是,您仍然应该测试“某些”情况。
让我们结合一些我不得不选择JavaScript的RegEx引擎的示例,因为我可以轻松地在浏览器中对其进行测试,并且因为在使用RegEx文字时无需进行任何转义字符串。
当您进行正常的字符串匹配时,您将一个字符串值与另一个字符串值进行测试。它们可以来自任何地方,但最终需要将两个字符串与另一个字符串进行比较:
if ( 'foo' == 'bar' ) doSomething();
这个例子很烂,因为它永远不会做任何事情
if ( foo == 'bar' ) doSomething();
好多了; 现在,我们实际上并不提前知道是否会做某事。现在我们可以开始接受用户输入了:
if ( prompt( 'Say "bar" to do something.' ) == 'bar' ) doSomething();
bar
令人惊奇的是,现在用户可以输入内容,并且会发生一些事情,直到您收到用户的错误报告,指出它们"bar"
不起作用或“ BAR”不起作用,或者他们键入了BRA
100次而没有任何反应。
忽略拼写错误和多余的字符,'bar' != 'BAR'
程序员需要考虑一种测试字符错误情况的方法。
简单的解决方案,使用toLowerCase
。效果很好,但是当您匹配时,使用英式英语而不是美式英语的用户又如何something == 'color'
呢?现在您必须匹配something == 'color' || somthing == 'colour'
。
长话短说,简单的模式很快就会变成大量重复的代码。
颜色示例可以简单地与以下内容匹配:
/colou?r/.test( something )
对正则表达式的基础知识有扎实的了解,可以大大减少您浪费大量时间重新发明轮子。
大多数实现正则表达式的语言至少都有一种资源可用于在该语言中使用正则表达式的特定语法。在MDN上可以找到一种JavaScript
阅读。
所有的。
然后再读一遍。
学习需要花费时间,将其视为一项投资:学习RegEx一个小时现在可以在下次需要进行一些字符串模式匹配时节省一个小时,然后在下一次节省一个小时。
在阅读了有关RegEx的全部内容之后,您可能不会了解其中的大部分内容。那是因为您实际上并没有做任何事情。
我提到了为什么我在本示例中选择JS,敦促您在浏览器中对其进行修改。速度很快,您可以直接在网址栏中进行操作。
JS有几种不同的使用RegEx的简单方法:
string.match( regex )
regex.exec( string )
regex.test( string )
从简单的东西开始:
javascript:'color'.match(/colou?r/);
是您踏进门的简单方法。试一试,打破它,看看什么匹配,什么不匹配。
当您坚持练习时,请继续30
。您需要阅读以了解更多信息,但您需要进行练习以真正了解所学内容。
Brian Kernighan在《Beautiful Code》一书中编写了一个简单的正则表达式处理器。我意识到您不是在寻找资源,但是在内部看到一个基本的实现可能会有所帮助。
在常规开发中,调试代码可以提供非常有用的见解。正则表达式没有什么不同。因此,冒着听起来像是广告的风险,请获取RegexBuddy。它有一个很棒的工具,可以直观地显示引擎在处理表达式和输入字符串时正在做什么。
正则表达式很快就会变得非常复杂,因此建议您使用教程开始学习。知道正则表达式最简单的形式是代表您要搜索的字符串。不幸的是,为了能够定义特殊的搜索规则,它需要某些字符,并且必须对这些字符进行转义,否则您将创建无效或不正确的正则表达式。
我的建议是从您要搜索的示例开始,然后转义它。因此,换句话说,如果您要查找括号中的任何内容,请以您要搜索的文本中的一个这样的字符串为例: (this is an example of something you'd want to find)
首先转义字符,以便搜索文字字符:
\(this is an example of something you'd want to find\)
测试它,验证它可以正确找到您的示例。然后,对表达式进行泛化以查找任何此类文本,而不仅仅是找到的示例。因此,它将变为:(
\([^)]*\)
表示任意数量的出现(包括0)都不是“”的任何字符)。
再次进行测试,并验证它不仅可以找到您的示例,还可以验证其他示例。在Internet上搜索更复杂但更频繁的正则表达式,并使用您现有的正则表达式对其进行修补,从而不必担心每种可能性。
就是这样 哦,学习并爱\ Q ... \ E。在大多数正则表达式语言中,\ Q表示文字模式的开头,\ E表示结尾,以防万一您必须搜索特别复杂的模式而又不知道如何转义它们。那挽救了我的生命不止两次。
我将为您提供一个简单问题的简单答案。首先,您需要了解什么是正则表达式(RegEx)-它们的作用以及它们的用途。然后,这是一个入门的好工具。
它是什么?RegEx是用于表达模式匹配的语言。就是说,使用它,您可以创建识别或发现文本模式的字符组合。这有什么用?在编程中,您可以告诉计算机匹配来自某些来源(用户输入,网页等)的文本,并检测其中是否包含特定的文本格式。例如,句点(。)代表任何字符-字母或数字。花括号中的数字表示迭代次数,因此“。{1,30}”表示任何字符,重复1到30次-换句话说,您不能有一个空字符串,并且长度不能超过30字符。它从那里继续。
如何开始学习?我见过的绝对最好的工具是Expresso,但这仅适用于Windows。它具有非常广泛的GUI,您可以在其中单击要添加到表达式中的元素,然后使用测试器根据各种输入对其进行检查以查看结果。我没有在Mac上看到任何好东西(但是我在VMWare上运行Windows,因此实际上并不需要Mac版本),也没有花很多时间在Linux上。
除了提供良好的参考以外,您真正学习的方法是使用良好的学习工具。一种是使用开源Vim编辑器,并设置了两个选项:
另一种是使用免费工具RegExCoach。您粘贴要搜索的文本,然后在另一个窗口中开发正则表达式。像Vim一样,它突出显示了成功的比赛。
您首先进行基本的字符串比较。很简单,但也没有那么强大。
接下来,您可能已经想过,需要区分大小写比较,以便“ greek”和“ GreeK”比较相等。这有点强大。
有一天,您会发现拼写上的细微差异不应阻止两个单词比较相等:即“ organize”和“ organize”应该比较相等。您坐下来并编写一些实现此目的的代码,您会感到很高兴。
直到您多一点抽象并意识到有时您希望所有以“ ize”结尾的单词都与他们的兄弟在英语拼写上相等。或者,某些字符串重复一定次数。而且,当然,您需要结合所有这些。
等等。最后,您很有可能最终得到一些注释,其中并非每个字符都代表自己。没什么是正则表达式。可以将其视为一组字符串的描述。
然后,这很容易,可以归结为以下3个基本原则:
您有基本的正则表达式:代表字符的字符,字符类,方便的字符类缩写,例如\ d或\ p {Lu}大写字母。
然后,您可以将它们组合在一起:如果r1和r2是正则表达式,则r1r2 r1 | r2(r1)也是如此。
最后但并非最不重要的是重复修饰符:r?r * r + r {n,m}
这是您最需要知道的。您可以在需要时查找其他任何内容。
另外两个很好的答案告诉您学习正则表达式背后的理论并进行实践,它们都是不错的建议。如果您是认真的人,我也建议您使用一个好的视觉正则表达式工具来帮助您。
例如,RegexBuddy具有视觉调试模式,可让您逐步执行正则表达式的执行,并通过突出显示和说明性文本向您显示正则表达式引擎在每个步骤中的工作。他们的网站上有一个视频演示了此调试过程。
我们可以为您提供的一切都是更多的学习资源。这个问题本身就是一种资源。
顺便说一句,我已经很容易从以下站点学到正则表达式:http : //www.regular-expressions.info/
我通过学习flex和bison来学习正则表达式,而flex和bison用于构建词法分析器和解析器。没有正则表达式,就不可能有一个解析器,而lexx和yacc这本书非常擅长于不费吹灰之力地完成理论研究。
从根本上讲,这些天实际上所有正则表达式引擎都遵循相同的原则。它们都是有限状态机,如果您真正理解了这一点,那么您几乎可以编写任何代码。它类似于学习递归,一旦获得递归,便可以将其本能地应用于问题。使用正确的工具很容易解决问题,但是如果没有正确的工具则很难解决。
与正则表达式相比,学习lexx和yacc的另一件事是您了解它们在内部如何工作。程序的前瞻性,完成比赛的原因,保存数据的方式等等。了解指针是绝对必须的,但是如果您掌握了lexx和yacc并从一开始就进行了遍历,那么您将学到您所要求的一切,并且拥有一个功能强大的工具,可用于您的其余职业。
这个问题包括大量学习资源,以及我扔在一起的flex骨架。
再次,我首先尝试确保没有更简单的方法来解决问题/“使字符串变”。
当您找不到一个时,我将其视为一个问题,而不是尝试从字符串中匹配您想要的内容,而是不匹配您不需要的内容。这主要是因为正则表达式是贪婪的。但这很好地为我提供了获得我想要的方法。
这是一个例子:
string = "Sep 22 19:57:38 host fcron[9137]: \
Job fbsetbg -r $HOME/backgrounds/ \
started for user user (pid 9138)"
匹配分钟:
string.match /^\w+\s\d+\s\d+:(\d+):\d+\s\w+\s/ # correct but bad
string.match /\d+:([^:]+):\d+/ # correct and good
与其去寻找时间,不如去寻找与众不同的界限。
这个例子有些人为,但是我可以提出。
我使用的一种方法是找到一堆需要语法更新的开源项目,然后编写一个越来越复杂的sed脚本,该脚本由许多正则表达式组成。
该脚本需要针对每个开源项目中的许多不同文件运行。然后针对具有不同样式的许多不同项目运行。我从一个非常简单的东西开始,%s/before/after
然后发现它匹配太多案例。所以我添加了更多的东西来防止这种情况。然后,我发现使用不同语法样式的不同项目需要进行不同的更改。
最后我最终得到了
并且由于需要
我还将顺带一提,有很多网站可以支持各种语言-红宝石,JavaScript等,使您可以随意处理表达式和示例文本,以备不时之需。这些是:
一个站点上多种语言的正则表达式
关注比赛组:
我发现学习正则表达式类似于学习乘法表-是的,您需要了解其背后的思想,但最终,您只需要经常重复进行此操作即可。
当我学习时,我将自己设定为每天进行几次正则表达式练习的目标。实际上,这意味着至少每天一次,我将尝试查看屏幕上的字符串或文本,然后提出一个挑战-“我可以从这里获取所有电子邮件地址”还是“找到所有“代码”一词用作动词而不是名词的出现。”
这样做了几个星期确实很有意义-当然,需要定期检查和复习。我要交一个。
我发现此在线工具也很有帮助,因为它让我实时测试了正则表达式:http : //www.gethifi.com/tools/regex