jjzjj

regex - 转到正则表达式通配符以获取没有周围文本的标签

coder 2024-07-06 原文

我正在尝试获取以下值“完成”,该值位于分块 http 流末尾返回的 byte slice 中。

X-sync-status: done\r\n

这是我到目前为止所做的 go 正则表达式

syncStatusRegex = regexp.MustCompile("(?i)X-sync-status:(.*)\r\n")

我只想让它返回这个位

(.*)

这是获取状态的代码

syncStatus := strings.TrimSpace(string(syncStatusRegex.Find(body)))
fmt.Println(syncStatus)

如何让它只返回“完成”而不是标题?

谢谢

最佳答案

您想要实现的是访问捕获组。我更喜欢命名捕获组,有一个非常简单的辅助函数可以处理这个问题:

package main

import (
    "fmt"
    "regexp"
)

// Our example input
const input = "X-sync-status: done\r\n"

// We anchor the regex to the beginning of a line with "^".
// Then we have a fixed string until our capturing group begins.
// Within our capturing group, we want to have all consecutive non-whitespace,
// non-control characters following.
const regexString = `(?i)^X-sync-status: (?P<status>\w*)`

// We ensure our regexp is valid and can be used.
var syncStatusRegexp *regexp.Regexp = regexp.MustCompile(regexString)


// The helper function...
func namedResults(re *regexp.Regexp, in string) map[string]string {

    // ... does the matching
    match := re.FindStringSubmatch(in)

    result := make(map[string]string)

    // and puts the value for each named capturing group
    // into the result map
    for i, name := range re.SubexpNames() {
        if i != 0 && name != "" {
            result[name] = match[i]
        }
    }
    return result
}

func main() {
    fmt.Println(namedResults(syncStatusRegexp, input)["status"])
}

Run on playground

Note Your current regexp is somewhat faulty, since you would capture whitespace as well. With your current regexp, the result would be " done" instead of "done".

编辑:当然,不用正则表达式你可以更便宜地做到这一点:

fmt.Print(strings.Trim(strings.Split(input, ":")[1], " \r\n"))

Run on playground

Edit2 我很好奇拆分方法便宜多少,因此我想出了非常粗略的方法:

package main

import (
    "fmt"
    "log"
    "regexp"
    "strings"
)

// Our example input
const input = "X-sync-status: done\r\n"

// We anchor the regex to the beginning of a line with "^".
// Then we have a fixed string until our capturing group begins.
// Within our capturing group, we want to have all consecutive non-whitespace,
// non-control characters following.
const regexString = `(?i)^X-sync-status: (?P<status>\w*)`

// We ensure our regexp is valid and can be used.
var syncStatusRegexp *regexp.Regexp = regexp.MustCompile(regexString)

func statusBySplit(in string) string {
    return strings.Trim(strings.Split(input, ":")[1], " \r\n")
}

func statusByRegexp(re *regexp.Regexp, in string) string {
    return re.FindStringSubmatch(in)[1]
}

[...]

还有一点基准:

package main

import "testing"

func BenchmarkRegexp(b *testing.B) {
    for i := 0; i < b.N; i++ {
        statusByRegexp(syncStatusRegexp, input)
    }
}

func BenchmarkSplit(b *testing.B) {
    for i := 0; i < b.N; i++ {
        statusBySplit(input)
    }
}

然后,我让它们分别在一个、两个和四个可用的 CPU 上运行 5 次。恕我直言,结果非常有说服力:

go test -run=^$ -test.bench=.  -test.benchmem -test.cpu 1,2,4 -test.count=5
goos: darwin
goarch: amd64
pkg: github.com/mwmahlberg/so-regex
BenchmarkRegexp          5000000               383 ns/op              32 B/op          1 allocs/op
BenchmarkRegexp          5000000               382 ns/op              32 B/op          1 allocs/op
BenchmarkRegexp          5000000               382 ns/op              32 B/op          1 allocs/op
BenchmarkRegexp          5000000               382 ns/op              32 B/op          1 allocs/op
BenchmarkRegexp          5000000               384 ns/op              32 B/op          1 allocs/op
BenchmarkRegexp-2        5000000               384 ns/op              32 B/op          1 allocs/op
BenchmarkRegexp-2        5000000               382 ns/op              32 B/op          1 allocs/op
BenchmarkRegexp-2        5000000               384 ns/op              32 B/op          1 allocs/op
BenchmarkRegexp-2        5000000               382 ns/op              32 B/op          1 allocs/op
BenchmarkRegexp-2        5000000               382 ns/op              32 B/op          1 allocs/op
BenchmarkRegexp-4        5000000               382 ns/op              32 B/op          1 allocs/op
BenchmarkRegexp-4        5000000               382 ns/op              32 B/op          1 allocs/op
BenchmarkRegexp-4        5000000               380 ns/op              32 B/op          1 allocs/op
BenchmarkRegexp-4        5000000               380 ns/op              32 B/op          1 allocs/op
BenchmarkRegexp-4        5000000               377 ns/op              32 B/op          1 allocs/op
BenchmarkSplit          10000000               161 ns/op              80 B/op          3 allocs/op
BenchmarkSplit          10000000               161 ns/op              80 B/op          3 allocs/op
BenchmarkSplit          10000000               164 ns/op              80 B/op          3 allocs/op
BenchmarkSplit          10000000               165 ns/op              80 B/op          3 allocs/op
BenchmarkSplit          10000000               162 ns/op              80 B/op          3 allocs/op
BenchmarkSplit-2        10000000               159 ns/op              80 B/op          3 allocs/op
BenchmarkSplit-2        10000000               167 ns/op              80 B/op          3 allocs/op
BenchmarkSplit-2        10000000               161 ns/op              80 B/op          3 allocs/op
BenchmarkSplit-2        10000000               159 ns/op              80 B/op          3 allocs/op
BenchmarkSplit-2        10000000               159 ns/op              80 B/op          3 allocs/op
BenchmarkSplit-4        10000000               159 ns/op              80 B/op          3 allocs/op
BenchmarkSplit-4        10000000               161 ns/op              80 B/op          3 allocs/op
BenchmarkSplit-4        10000000               159 ns/op              80 B/op          3 allocs/op
BenchmarkSplit-4        10000000               160 ns/op              80 B/op          3 allocs/op
BenchmarkSplit-4        10000000               160 ns/op              80 B/op          3 allocs/op
PASS
ok      github.com/mwmahlberg/so-regex  61.340s

它清楚地表明,在拆分标签的情况下,实际使用拆分的速度是预编译 正则表达式的两倍多。对于您的用例,我显然会选择使用拆分。

关于regex - 转到正则表达式通配符以获取没有周围文本的标签,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57934715/

有关regex - 转到正则表达式通配符以获取没有周围文本的标签的更多相关文章

  1. ruby - 使用 ruby​​ 将 HTML 转换为纯文本并维护结构/格式 - 2

    我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h

  2. ruby - 在院子里用@param 标签警告 - 2

    我试图使用yard记录一些Ruby代码,尽管我所做的正是所描述的here或here#@param[Integer]thenumberoftrials(>=0)#@param[Float]successprobabilityineachtrialdefinitialize(n,p)#initialize...end虽然我仍然得到这个奇怪的错误@paramtaghasunknownparametername:the@paramtaghasunknownparametername:success然后生成的html看起来很奇怪。我称yard为:$yarddoc-mmarkdown我做错了什么?

  3. ruby 正则表达式 - 如何替换字符串中匹配项的第 n 个实例 - 2

    在我的应用程序中,我需要能够找到所有数字子字符串,然后扫描每个子字符串,找到第一个匹配范围(例如5到15之间)的子字符串,并将该实例替换为另一个字符串“X”。我的测试字符串s="1foo100bar10gee1"我的初始模式是1个或多个数字的任何字符串,例如,re=Regexp.new(/\d+/)matches=s.scan(re)给出["1","100","10","1"]如果我想用“X”替换第N个匹配项,并且只替换第N个匹配项,我该怎么做?例如,如果我想替换第三个匹配项“10”(匹配项[2]),我不能只说s[matches[2]]="X"因为它做了两次替换“1fooX0barXg

  4. css - 用 watir 检查标签类? - 2

    我有一个div,它根据表单是否正确提交而改变。我想知道是否可以检查类的特定元素?开始元素看起来像这样。如果输入不正确,添加错误类。 最佳答案 试试这个:browser.div(:id=>"myerrortest").class_name更多信息:http://watir.github.com/watir-webdriver/doc/Watir/HTMLElement.html#class_name-instance_method另一种选择是只查看具有您期望的类的div是否存在browser.div((:id=>"myerrortes

  5. ruby - 正则表达式将非英文字母匹配为非单词字符 - 2

    @raw_array[i]=~/[\W]/非常简单的正则表达式。当我用一些非拉丁字母(具体来说是俄语)尝试时,条件是错误的。我能用它做什么? 最佳答案 @raw_array[i]=~/[\p{L}]/使用西里尔字符进行测试。引用:http://www.regular-expressions.info/unicode.html#prop 关于ruby-正则表达式将非英文字母匹配为非单词字符,我们在StackOverflow上找到一个类似的问题: https://

  6. ruby - 正则表达式在哪个位置失败? - 2

    我需要一个非常简单的字符串验证器来显示第一个符号与所需格式不对应的位置。我想使用正则表达式,但在这种情况下,我必须找到与表达式相对应的字符串停止的位置,但我找不到可以做到这一点的方法。(这一定是一种相当简单的方法……也许没有?)例如,如果我有正则表达式:/^Q+E+R+$/带字符串:"QQQQEEE2ER"期望的结果应该是7 最佳答案 一个想法:你可以做的是标记你的模式并用可选的嵌套捕获组编写它:^(Q+(E+(R+($)?)?)?)?然后你只需要计算你获得的捕获组的数量就可以知道正则表达式引擎在模式中停止的位置,你可以确定匹配结束

  7. ruby - 有没有办法从 ruby​​ case 语句中访问表达式? - 2

    我想从then子句中访问c​​ase语句表达式,即food="cheese"casefoodwhen"dip"then"carrotsticks"when"cheese"then"#{expr}crackers"else"mayo"end在这种情况下,expr是食物的当前值(value)。在这种情况下,我知道,我可以简单地访问变量food,但是在某些情况下,该值可能无法再访问(array.shift等)。除了将expr移出到局部变量然后访问它之外,是否有直接访问caseexpr值的方法?罗亚附注我知道这个具体示例很简单,只是一个示例场景。 最佳答案

  8. ruby - 正则表达式 - 排除一个字符 - 2

    这是一个例子:s="abcd+subtext@example.com"s.match(/+[^@]*/)Result=>"+subtext"问题是,我不想在其中包含“+”。我希望结果是“潜台词”,没有+ 最佳答案 您可以在正则表达式中使用括号来创建匹配组:s="abcd+subtext@example.com"s=~/\+([^@]*)/&&$1=>"subtext" 关于ruby-正则表达式-排除一个字符,我们在StackOverflow上找到一个类似的问题:

  9. ruby - 如何遍历 Ruby 中所有正则表达式匹配的字符串? - 2

    我们有一个字符串:“”这个正则表达式://i如何从当前字符串中获取所有匹配项? 最佳答案 "".scan(//)参见scan在ruby​​-docs上 关于ruby-如何遍历Ruby中所有正则表达式匹配的字符串?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/6857852/

  10. ruby-on-rails - rspec - 我怎样才能让 "pendings"有我的文本而不仅仅是 "No reason given" - 2

    我有这个代码:context"Visitingtheusers#indexpage."dobefore(:each){visitusers_path}subject{page}pending('iii'){shouldhave_no_css('table#users')}pending{shouldhavecontent('Youhavereachedthispageduetoapermissionic错误')}它会导致几个待处理,例如ManagingUsersGivenapractitionerloggedin.Visitingtheusers#indexpage.#Noreason

随机推荐