在这里,我们将给大家分享关于使用正则表达式解析HTML:为什么不呢?的知识,让您更了解正则匹配html的本质,同时也会涉及到如何更有效地c#–使用正则表达式解析VBAConst声明…、golang使用
在这里,我们将给大家分享关于使用正则表达式解析 HTML:为什么不呢?的知识,让您更了解正则匹配html的本质,同时也会涉及到如何更有效地c# – 使用正则表达式解析VBA Const声明…、golang使用正则表达式解析网页、HTML5 使用正则表达式、java正则表达式解析html示例分享的内容。
本文目录一览:- 使用正则表达式解析 HTML:为什么不呢?(正则匹配html)
- c# – 使用正则表达式解析VBA Const声明…
- golang使用正则表达式解析网页
- HTML5 使用正则表达式
- java正则表达式解析html示例分享
使用正则表达式解析 HTML:为什么不呢?(正则匹配html)
似乎在stackoverflow上,提问者使用正则表达式从HTML中获取一些信息的每个问题都不可避免地会有一个“答案”,即不使用正则表达式来解析HTML。
为什么不?我知道那里有quote-unquote“真正的”HTML解析器,例如Beautiful
Soup,我相信它们功能强大且有用,但是如果您只是做一些简单,快速或肮脏的事情,那么为什么当一些正则表达式就可以正常工作时,还要麻烦使用如此复杂的东西吗?
此外,对于正则表达式,是否有一些我不了解的基本知识使它们成为一般解析的糟糕选择?
答案1
小编典典正则表达式无法进行整个 HTML 解析,因为它依赖于匹配开始和结束标记,而这在正则表达式中是不可能的。
正则表达式只能匹配正则语言,但 HTML
是上下文无关语言而 不是
正则语言(正如@StefanPochmann 指出的,正则语言也是上下文无关的,因此上下文无关并不一定意味着不是正则语言)。在 HTML
上使用正则表达式唯一可以做的就是启发式方法,但这并不适用于所有条件。应该有可能呈现一个将被任何正则表达式错误匹配的 HTML 文件。
c# – 使用正则表达式解析VBA Const声明…
这些工作很漂亮:
> Const foo = 123
> Const foo $=“123”
> Const foo As String =“123”
>私人Const foo = 123
> Public Const foo As Integer = 123
>全球Const foo%= 123
但我有两个问题:
>如果声明末尾有评论,我会将其作为价值的一部分:
Const foo = 123 'this comment is included as part of the value
>如果在同一条指令中声明了两个或多个常量,则无法匹配整个指令:
Const foo = 123,bar = 456
这是我正在使用的正则表达式:
/// <summary> /// Gets a regular expression pattern for matching a constant declaration. /// </summary> /// <remarks> /// Constants declared in class modules may only be <c>Private</c>. /// Constants declared at procedure scope cannot have an access modifier. /// </remarks> public static string GetConstantDeclarationSyntax() { return @"^((Private|Public|Global)\s)?Const\s(?<identifier>[a-zA-Z][a-zA-Z0-9_]*)(?<specifier>[%&@!#$])?(?<as>\sAs\s(?<reference>(((?<library>[a-zA-Z][a-zA-Z0-9_]*))\.)?(?<identifier>[a-zA-Z][a-zA-Z0-9_]*)))?\s\=\s(?<value>.*)$"; }
显然,这两个问题都是由(?< value>.*)$part引起的,它在行结束前匹配任何内容.我通过将整个模式封装在捕获组中并添加可选的逗号来使VariableNode支持多个声明,但由于常量具有此值组,因此执行该操作会导致第一个常量将所有后续声明作为其值的一部分捕获……让我回到问题#1.
我想知道是否可以用正则表达式来解决问题#1,因为该值可能是包含撇号的字符串,并且可能是一些转义(双倍)双引号.
我想我可以在ConstantNode类中解决它,在Value的getter中:
/// <summary> /// Gets the constant's value. Strings include delimiting quotes. /// </summary> public string Value { get { return RegexMatch.Groups["value"].Value; } }
我的意思是,我可以在这里实现一些额外的逻辑,做我用正则表达式做不到的事情.
如果问题#1可以通过正则表达式来解决,那么我相信问题#2也可以……或者我是否在正确的轨道上?我应该抛弃[相当复杂]的正则表达式模式并想到另一种方式吗?我不太熟悉贪婪的子表达式,反向引用和其他更高级的正则表达式功能 – 这是什么限制了我,或者仅仅是因为我使用错误的锤子钉这个钉子?
注意:模式可能与非法语法匹配并不重要 – 此代码仅针对可编译的VBA代码运行.
解决方法
正则表达式
为了使其工作得很好,您需要对VBA代码进行一些控制.如果您不能这样做,那么您真的需要考虑编写解析器而不是使用Regex.但是,根据你已经说过的话,你可能会有一些控制权.所以也许这会有所帮助.
所以为此,我不得不将正则表达式分成两个不同的正则表达式.原因是.Net Regex库无法处理重复组中的捕获组.
捕获行并开始解析,这会将变量(带有值)放入一个组中,但第二个正则表达式将解析它们.只是fyi,正则表达式使用负面的外观.
^(?:(?<Accessibility>Private|Public|Global)\s)?Const\s(?<variable>[a-zA-Z][a-zA-Z0-9_]*(?:[%&@!#$])?(?:\sAs)?\s(?:(?:[a-zA-Z][a-zA-Z0-9_]*)\s)?=\s[^',]+(?:(?:(?!"").)+"")?(?:,\s)?){1,}(?:'(?<comment>.+))?$
Regex Demo
这是解析变量的正则表达式
(?<identifier>[a-zA-Z][a-zA-Z0-9_]*)(?<specifier>[%&@!#$])?(?:\sAs)?\s(?:(?<reference>[a-zA-Z][a-zA-Z0-9_]*)\s)?=\s(?<value>[^',]+(?:(?:(?!").)+")?),?
Regex Demo
这里有一些c#代码你可以投入并测试一切.这样可以轻松测试您拥有的任何边缘情况.
static void Main(string[] args) { List<String> test = new List<string> { "Const foo = 123","Const foo$= \"123\"","Const foo As String = \"1'2'3\"","Const foo As String = \"123\"","Private Const foo = 123","Public Const foo As Integer = 123","Global Const foo% = 123","Const foo = 123 'this comment is included as part of the value","Const foo = 123,bar = 456","'Const foo As String = \"123\"",}; foreach (var str in test) Parse(str); Console.Read(); } private static Regex parse = new Regex(@"^(?:(?<Accessibility>Private|Public|Global)\s)?Const\s(?<variable>[a-zA-Z][a-zA-Z0-9_]*(?:[%&@!#$])?(?:\sAs)?\s(?:(?:[a-zA-Z][a-zA-Z0-9_]*)\s)?=\s[^',}(?:'(?<comment>.+))?$",RegexOptions.Compiled | RegexOptions.Singleline,new TimeSpan(0,20)); private static Regex variableRegex = new Regex(@"(?<identifier>[a-zA-Z][a-zA-Z0-9_]*)(?<specifier>[%&@!#$])?(?:\sAs)?\s(?:(?<reference>[a-zA-Z][a-zA-Z0-9_]*)\s)?=\s(?<value>[^',]+(?:(?:(?!"").)+"")?),?",20)); public static void Parse(String str) { Console.WriteLine(String.Format("Parsing: {0}",str)); var match = parse.Match(str); if (match.Success) { //Private/Public/Global var accessibility = match.Groups["Accessibility"].Value; //Since we defined this with atleast one capture,there should always be something here. foreach (Capture variable in match.Groups["variable"].Captures) { //Console.WriteLine(variable); var variableMatch = variableRegex.Match(variable.Value); if (variableMatch.Success) { Console.WriteLine(String.Format("Identifier: {0}",variableMatch.Groups["identifier"].Value)); if (variableMatch.Groups["specifier"].Success) Console.WriteLine(String.Format("specifier: {0}",variableMatch.Groups["specifier"].Value)); if (variableMatch.Groups["reference"].Success) Console.WriteLine(String.Format("reference: {0}",variableMatch.Groups["reference"].Value)); Console.WriteLine(String.Format("value: {0}",variableMatch.Groups["value"].Value)); Console.WriteLine(""); } else { Console.WriteLine(String.Format("Failed VARIABLE: {0}",variable.Value)); } } if (match.Groups["comment"].Success) { Console.WriteLine(String.Format("Comment: {0}",match.Groups["comment"].Value)); } } else { Console.WriteLine(String.Format("Failed: {0}",str)); } Console.WriteLine("+++++++++++++++++++++++++++++++++++++++++++++"); Console.WriteLine(""); }
c#代码就是我用来测试我的理论的代码,所以我为其中的疯狂道歉.
为了完整性,这里有一小部分输出样本.如果您运行代码,您将获得更多输出,但这直接表明它可以处理您询问的情况.
Parsing: Const foo = 123 'this comment is included as part of the value Identifier: foo value: 123 Comment: this comment is included as part of the value Parsing: Const foo = 123,bar = 456 Identifier: foo value: 123 Identifier: bar value: 456
它处理什么
以下是我可能会想到你可能感兴趣的主要案例.它应该仍然可以处理你之前所拥有的所有内容,因为我刚刚添加到你提供的正则表达式中.
>评论
>单行上的多个变量声明
>字符串值中的撇号(注释字符).即foo =“她太棒了”
>如果该行以注释开头,则应忽略该行
什么不处理
我没有真正处理的一件事是间距,但如果你需要的话,不应该在你自己中添加它.因此,例如,如果声明多个变量,则必须在逗号后面加一个空格.即(有效:foo = 123,foobar = 124)(无效:foo = 123,foobar = 124)
你不会对它的格式有太多的宽容,但是在使用正则表达式时,你可以做很多事情.
希望这可以帮助你,如果你需要任何更多解释如何工作,请告诉我.只知道这是一个坏主意.您将遇到正则表达式无法处理的情况.如果我在你的位置,我会考虑编写一个简单的解析器,从长远来看,它会给你更大的灵活性.祝好运.
golang使用正则表达式解析网页
废话少说,直接奉上代码:
package main
import (
"fmt"
"time"
"io/ioutil"
"net/http"
"regexp"
"strings"
)
func main() {
ip_pool := []string{
"172.16.1.128",
"172.16.1.129",
"172.16.1.131",
"172.16.1.132",
"172.16.1.133",
"172.16.1.134",
"172.16.1.135",
"172.16.1.136",
"172.16.1.137",
"172.16.1.138",
"172.16.1.190",
}
for {
for i:=0;i<len(ip_pool);i++ {
url := "http://"+ip_pool[i]+":10022"
//fmt.Println("-----------------",ip_pool[i],"---------")
get_url(url)
time.Sleep(1*time.Millisecond)
}
//time.Sleep(time.Second * 60)
}
}
func get_url(url string){
fmt.Println("----------",url,"----------------")
resp, err := http.Get(url)
if err != nil {
fmt.Println("http get error.")
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println("http read error")
}
src := string(body)
//将HTML标签全转换成小写
re, _ := regexp.Compile("\\<[\\S\\s]+?\\>")
src = re.ReplaceAllStringFunc(src, strings.ToLower)
// 提取table 标签
re,_ = regexp.Compile("\\<!doc[\\S\\s]+?\\<table")
src = re.ReplaceAllString(src, "<table")
re,_ = regexp.Compile("</table\\>[\\S\\s]+?\\</html\\>")
src = re.ReplaceAllString(src, "</table>")
// 干掉行首的空格
re,_ = regexp.Compile("()([\\S\\s\\<>\"\\d]+?)(\\\\<tr>)([\\S\\s\\<>\"\\d]+?)(\\</tr>)")
//src = re.ReplaceAllString(src, "$2")
src = re.ReplaceAllString(src, "$2]")
// 去掉<>标签
re,_ = regexp.Compile("<[\\S\\s]+?>")
src = re.ReplaceAllString(src, "")
re,_ = regexp.Compile("\n")
src = re.ReplaceAllString(src, "")
re,_ = regexp.Compile("[ ]+")
src = re.ReplaceAllString(src, " ")
re,_ = regexp.Compile("]")
src = re.ReplaceAllString(src, "\n")
// 变成 json 1 2 3 4
re,_ = regexp.Compile("(\\w*)(\\w{2}:\\w{2}:\\w{2}:\\w{2}:\\w{2}:\\w{2})([A-Za-z ]*)(\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2} )([V\\d\\.]* )(\\d{4}-\\d{2}-\\d{2}( \\d{2}:\\d{2}(:\\d{2})?)?)")
/* (((\\d{4}-\\d{2}-\\d{2})+ (\\d{2}:\\d{2}:\\d{2})*?)")
*/
src = re.ReplaceAllString(src, "$1,$2,$3,$4,$5,$6,")
//re,_ = regexp.Compile("(<[\\S\\s]*?\">)([\\S\\s]+?)(</t")
//src = re.ReplaceAllString(src, "$2,")
// re,_ = regexp.Compile("<[\\S\\s]+?>")
// src = re.ReplaceAllString(src, "")
//reg := regexp.MustCompile("([A-Za-z]+?)(\n[\\s]+)([\\d]+)")
// src = reg.ReplaceAllString(src, "$1:$3")
//去除连续的换行符
//re, _ = regexp.Compile("\\s{2,}")
//src = re.ReplaceAllString(src, "\n")
//re = regexp.MustCompile("\n\\d+")
//fmt.Println(re.ReplaceAllLiteralString("hello\n2\nwork", ''\d''))
src = strings.Replace(src,"虚拟机名称 虚拟机MAC 虚拟机状态 心跳时间 引擎版本 病毒库日期 扫描样本数" , "vm_name,vm_mac,vm_state,vm_heart,vm_eg,vm_av_db,vm_count",-1)
fmt.Println(src)
//reg, err := regexp.Compile("[[0-9A-Za-z]{2}:?]{6}")
//fmt.Printf("%q,%v\n", reg.FindString("00:16:3e:4a:29:35"), err)
// "Hello",
// text := "Hello\n123\nGo\n123"
// reg = regexp.MustCompile("([A-Za-z]+?)(\n)([\\d]+)")
// fmt.Printf("%q\n", reg.ReplaceAllString(text, "$3:$1"))
//fmt.Println(strings.TrimSpace(src))
//去除STYLE
//re, _ = regexp.Compile("\\<style[\\S\\s]+?\\</style\\>")
//src = re.ReplaceAllString(src, "")
//去除SCRIPT
//re, _ = regexp.Compile("\\<script[\\S\\s]+?\\</script\\>")
//src = re.ReplaceAllString(src, "")
//去除所有尖括号内的HTML代码,并换成换行符
//re, _ = regexp.Compile("\\<[\\S\\s]+?\\>")
//src = re.ReplaceAllString(src, "\n")
//去除连续的换行符
//re, _ = regexp.Compile("\\s{2,}")
//src = re.ReplaceAllString(src, "\n")
//fmt.Println(strings.TrimSpace(src))
}
以上就是本文给大家分享的代码了,希望大家能够喜欢。
- Golang 正则匹配效率详解
- 浅析golang 正则表达式
- golang正则之命名分组方式
HTML5 使用正则表达式
下面是小编 jb51.cc 通过网络收集整理的代码片段。
小编小编现在分享给大家,也给大家做个参考。
<form action="" method="post"> <label for="username">Create a Username: </label> <input type="text" name="username" id="username" placeholder="4 <> 10" pattern="[A-Za-z]{4,10}" autofocus required> <button type="submit">Go </button> </form>
以上是小编(jb51.cc)为你收集整理的全部代码内容,希望文章能够帮你解决所遇到的程序开发问题。
如果觉得小编网站内容还不错,欢迎将小编网站推荐给程序员好友。
java正则表达式解析html示例分享
package work;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.getmethod;
import org.apache.commons.httpclient.params.HttpMethodParams;
public class chuanboyi {
public static void main(String[] args){
// Todo Auto-generated method stub
StringBuffer html = new StringBuffer();
HttpClient httpclient = new HttpClient();
//创建GET方法实例
getmethod getmethod = new getmethod("http://www.jb51.net");
//使用系统提供的默认恢复策略
getmethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,new DefaultHttpMethodRetryHandler());
try{
//执行GET方法
int statusCode = httpclient.executeMethod(getmethod);
if(statusCode != HttpStatus.SC_OK){
System.out.println("Method is wrong " + getmethod.getStatusLine());
}
InputStream responseBody = getmethod.getResponseBodyAsstream();
BufferedReader reader = new BufferedReader(new InputStreamReader(responseBody,"utf-8"));
String line = reader.readLine();
while(line != null){
html.append(line).append("\n");
line = reader.readLine();
}
reader.close();
//正则表达式
String regex = "<form name=\"compareForm\"[\\s\\S]+>[\\s\\S]+</form>.*<script.*>";
String regexa ="(?<=<li>)[\\s\\S]+?(?=</li>)";
Pattern pattern = Pattern.compile(regex);
Matcher m = pattern.matcher(html);
StringBuffer str = new StringBuffer();
int i = 0;
while(m.find()){
str.append(m.group());
}
pattern = Pattern.compile(regexa);
m = pattern.matcher(str);
while(m.find()){
attrs(m.group());
i++;
}
System.out.println("共有"+i+"条数据!");
}catch (HttpException e) {
// Todo: handle exception
System.out.println("Please check your provided http address!");
e.printstacktrace();
}catch (IOException e) {
// Todo: handle exception
System.out.println("the line is wrong!");
e.printstacktrace();
}finally{
getmethod.releaseConnection();//释放链接
}
}
public static void attrs(String str){
//获取url的正则表达式
String regexURL = "[a-z]+-[0-9]+\\.html";
//获取Name的正则表达式
String regexName = "(?<=title=\")[[\\w-\\s][^x00-xff]]+(?=\")";
//获取图片的正则表达式
String regexPicture = "images.*\\.jpg";
Pattern patternURL = Pattern.compile(regexURL);
Pattern patternName = Pattern.compile(regexName);
Pattern patternPicture = Pattern.compile(regexPicture);
Matcher mURL = patternURL.matcher(str);
Matcher mName = patternName.matcher(str);
Matcher mPicture = patternPicture.matcher(str);
if(mName.find()){
System.out.println("名字:"+mName.group());
}
if(mURL.find()){
System.out.println("链接:"+mURL.group());
}
if(mPicture.find()){
System.out.println("图片:"+mPicture.group());
}
}
}