正则表达式

正则表达式在日常开发中时不时都会遇到,我们先来看看正则表达式( Regular Expression)的定义(参考龙书英文第2版121页):

ε是一个正则表达式,它生成的语言L(ε)等价于{ε},即L(ε)={ε},就是一个空字符串

如果a属于符号集Σ,那么a也是一个正则表达式,且其生成的语言L(a)={a},就是一个a字符

如果r和s都是正则表达式,那么r | s也是正则表达式,L(r | s) = L(r) ∪ L(s)

如果r和s都是正则表达式,那么r s也是正则表达式,L(r s) = L(r) L(s)

如果r是正则表达式,则r*也是正则表达式,L(r*)=(L(r))*

如果r是正则表达式,则(r)也是正则表达式,L((r))=L(r)

来看看正则表达式的一些简单例子,假设字符表Σ是全部的小写字母(a~z)以及阿拉伯数字(0~9),则:

a

abc

a|b

ab|bc

a*

(ab)*

(a|b)(0|1)*

都是正则表达式。

正则定义

有时一个正则表达式很复杂,我们希望能够把这个正则表达式用记号记下来,以便以后使用,于是就有了正则定义(Regular Definitions)(参考龙书英文第2版123页):

设Σ是符号表,如果有一系列的定义:

d1 → r1

d2→ r2

...

dn→ rn

并且:

任一个di都是一个新的符号,它既不属于Σ,也不属于{d1,d2,d3,...,d(i-1)}

任一个ri都是一个正则表达式,能够由符号表Σ以及{d1,d2,d3,...,d(i-1)}所表示

这样就构成了一组正则表达式定义。

上下文无关文法

上下文无关文法(Context-Free Grammar)的定义参考龙书英文第2版197页:

终结符号(Terminals)

非终结符号(Nonterminals)

一个非终结符号作为开始符号

一组产生式

稍详细的内容可见我的另一篇博文 到底什么是上下文无关文法?

正则定义与上下文无关文法的区别

正则定义与上下文无关文法的重要区别在于,在正则定义中是不允许递归定义的,例如A → aA|b不是一个正则定义,为其左边的A必须是一个新的符号,也就是说不能在其他地方定义过,胆识其右边要求每一个符号都是定义过的,因此这个定义无法满足。而上下文无关文法则没有这个约束,因此A → aA|b是一个上下文无关文法的产生式,但不是正则定义的定义式。

看过一段话,意思是正则表达式在编译器构建中一般用来进行词法分析,通过NFA、DFA就可以识别,而更复杂的文法就需要以来其他算法了。

Regular expressions and BNF are two grammatical formalisms for describing sets of strings. Regular expressions are a concise and convenient notation for describing syntax when "nesting" is not an issue. BNF is a more powerful notation that allows for the description of nested language constructs using nonterminal symbols in arbitrary recursive combinations. Thus regular expressions are appropriate for token-level syntax of programming languages, while BNF is required for the higher-level recursive syntax of expressions, statements and so on.

原文请看 http://www.cs.sfu.ca/~cameron/Teaching/D-Lib/RegExp.html

运用正则定义的要求,我们可以从上下文无关文法中,筛选出符合正则定义的产生式,这些符合正则定义的产生式,就可以用来生成有限状态自动机。

下面的类实现了从上下文无关文法产生式中筛选处正则定义式:

/*

This file is one of the component a Context-free Grammar Parser Generator,

which accept a piece of text as the input, and generates a parser

for the inputted context-free grammar.

Copyright (C) 2013, Junbiao Pan (Email: panjunbiao@gmail.com)

This program is free software: you can redistribute it and/or modify

it under the terms of the GNU General Public License as published by

the Free Software Foundation, either version 3 of the License, or

any later version.

This program is distributed in the hope that it will be useful,

but WITHOUT ANY WARRANTY; without even the implied warranty of

MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the

GNU General Public License for more details.

You should have received a copy of the GNU General Public License

along with this program. If not, see .

*/

package analyzer;

import java.io.IOException;

import java.util.ArrayList;

import java.util.HashSet;

import java.util.List;

import java.util.Set;

import abnf.Rule;

import abnf.RuleName;

public class RegularAnalyzer {

private List nonRegularRules = new ArrayList();

public List getNonRegularRules() { return nonRegularRules; }

private List regularRules = new ArrayList();

public List getRegularRules() { return regularRules; }

private List undefinedRules = new ArrayList();

public List getUndefinedRules() { return undefinedRules; }

public RegularAnalyzer(List rules) {

Set definedRuleNames = new HashSet();

List observedRules = new ArrayList();

observedRules.addAll(rules);

boolean foundRegular;

do {

foundRegular = false;

for(int index = observedRules.size() - 1; index >= 0; index --) {

Set dependent = observedRules.get(index).getElements().getDependentRuleNames();

if (definedRuleNames.containsAll(dependent)) {

definedRuleNames.add(observedRules.get(index).getRuleName());

regularRules.add(observedRules.get(index));

observedRules.remove(index);

foundRegular = true;

continue;

}

if (!dependent.contains(observedRules.get(index).getRuleName())) {

continue;

}

dependent.remove(observedRules.get(index).getRuleName());

if (definedRuleNames.containsAll(dependent)) {

definedRuleNames.add(observedRules.get(index).getRuleName());

nonRegularRules.add(observedRules.get(index));

observedRules.remove(index);

foundRegular = true;

}

}

} while (foundRegular);

undefinedRules.addAll(observedRules);

observedRules.clear();

}

}

上下文无关输入与输出java_正则表达式与上下文无关文法相关推荐

  1. Racket编程指南——8 输入和输出

    8 输入和输出 一个Racket端口对应一个流的Unix概念(不要与racket/stream的流混淆). 一个Racket端口(port)代表一个数据源或数据池,诸如一个文件.一个终端.一个TCP连 ...

  2. python 去除字符串的标点符号 用_Python输入和输出

    点击上方Python知识圈,设为星标 回复1024获取Python资料 阅读文本大概需要 5 分钟 近期精彩文章:Python100例(附PDF下载地址) 在很多时候,你会想要让你的程序与用户(可能是 ...

  3. python中倒着输出输入值_十五、深入Python输入和输出

    「@Author:By Runsen」 在很多时候,你会想要让你的程序与用户(可能是你自己)交互.你会从用户那里得到输入,然后打印一些结果.我们可以使用input和print语句来完成这些功能. in ...

  4. vb教材笔记_VB课堂笔记-----第五章 数据的输入与输出

    第五章 数据的输入与输出(笔试2-4分) 需要掌握:3个方法.2个函数.1个语句 一.Print输出方法 格式: 对象名.Print 表达式-- 功能:输出表达式的结果(计算和输出) 注: 1)对象名 ...

  5. (13.1.2)PMBOK之二:五大过程组及其涉及的输入、输出、工具技术

    一.五大过程组概述 1.1 过程的定义 1.2 五大过程组的由来 1.3 五大过程组49 1.3.1 启动 2 13% 1.3.2 规划 24 24% 1.3.3 执行 10 30% 1.3.4 监控 ...

  6. web安全性测试用例(输入、输出、SQL注入、跨站请求伪造(CSRF)、跨站脚本攻击(XSS))实实在在的干货

    https://www.cnblogs.com/qmfsun/p/3724406.html 建立整体的威胁模型,测试溢出漏洞.信息泄漏.错误处理.SQL 注入.身份验证和授权错误. 1.   输入验证 ...

  7. 线性系统与非线性系统、定常系统和时变系统、连续系统和离散系统、单输入单输出系统与多输入多输出系统(自动控制原理)

    目录 线性系统与非线性系统 线性系统 线性系统 定常系统和时变系统 定常系统 时变系统 连续系统和离散系统 连续系统 离散系统 单输入单输出系统与多输入多输出系统 单输入单输出系统 多输入多输出系统( ...

  8. 【Python核心】输入与输出

    由浅及深讲讲Python的输入和输出 一.输入输出基础 最简单直接的输入来自键盘操作,比如下面这个例子 name = input('your name:') gender = input('you a ...

  9. c++ 输入、输出和文件

    输入.输出和文件 架构 iostream 概述 重定向 cout 概述 其他ostream 方法 刷新输出缓冲区 cout格式化 cin 文件输入和输出 简单的文件IO 流状态位 命令行处理技术 文件 ...

  10. 第25章 Python3 输入和输出教程

    在前面几个章节中,咱们其实已经接触了 Python 的输入输出的功能.本章节咱们将具体介绍 Python 的输入输出. 输出格式美化 Python两种输出值的方式: 表达式语句和 print() 函数 ...

最新文章

  1. MyBatis之使用resultMap实现高级映射
  2. 最优化学习笔记(十九)——拟牛顿法(5)BFGS算法
  3. 小米6钉子户们的胜利!复刻机可能要来了,目前已在工程验证阶段
  4. iOS9使用提示框的正确实现方式(UIAlertView is deprecated)
  5. 给开发说:今天上线!
  6. python 字典排序成绩_原来python中dict()的高级用法可以这样实现!真是让我长了见识...
  7. Python3.6全栈开发实例[013]
  8. java软件开发工程师的简历
  9. 宽带波形测试软件,适用于5G时代的波形测试分析系统是怎样的?
  10. android+反编译加广告,追书神器Android版,反编译去广告基本教程
  11. GaN制备Micro-led(二)——光子晶体倒装 Micro-LED 制备的关键工艺(纳米压印光刻、干法刻蚀、介质薄膜沉积、物理气相沉积)
  12. MAC用虚拟机启动移动固态硬盘的系统
  13. 2020TB618喵币挂机自动获取脚本(jsapp)
  14. 阿里P9:聊聊大厂晋升的“潜规则”
  15. 最好的在线PDF转换工具服务
  16. php 图片木马检测
  17. 关于“智能革命”的分析与思考
  18. Nexus的安装和使用
  19. FPGA学习前导:FPGA/CPLD简介
  20. 基础练习 时间转换(给定一个以秒为单位的时间t,要求用“<H>:<M>:<S>”的格式来表示这个时间。<H>表示时间,<M>表示分钟,而<S>表示秒,它们都是整数且没有前导的“0”。例如,若t=0,)

热门文章

  1. 【设计模式从青铜到王者】第八篇:创建型模式之建造者模式(BuilderPattern)
  2. 虚短虚断是怎么来的?长篇好文介绍深度负反馈
  3. idea2017永久性破解
  4. 给ftp服务器创建文件夹,ftp服务器上创建文件夹
  5. Python菜鸟教程
  6. 免费易用的Web版OFD阅读器
  7. 通过两个队列实现一个栈(C语言)
  8. IIS管理器FTP站点中FTP防火墙支持页面
  9. yolo系列之yolo v3【深度解析】
  10. MAX232(MAX3232)电平转换芯片的工作原理