Regex 在字符串中查找文件路径

Regex 在字符串中查找文件路径,regex,go,Regex,Go,我修改了gnome终端并添加了对自定义url处理程序的支持:src:// 它允许您在ctrl单击时直接跳转到文件中的行号 示例src:///path/to/file:43 这一切都很好,但现在我需要某种类型的过滤器,将所有相对和绝对路径转换为绝对src链接。然后我就可以通过管道将另一个程序输出 范例 $ go build # command-line-arguments ./test.go:3931: undefined: erre 我想要这样的东西 $ go build | src-lin

我修改了gnome终端并添加了对自定义url处理程序的支持:
src://

它允许您在
ctrl单击时直接跳转到文件中的行号

示例<代码>src:///path/to/file:43

这一切都很好,但现在我需要某种类型的过滤器,将所有相对和绝对路径转换为绝对
src
链接。然后我就可以通过管道将另一个程序输出

范例

$ go build

# command-line-arguments
./test.go:3931: undefined: erre
我想要这样的东西

$ go build | src-links

# command-line-arguments
src:///home/icholy/gocode/src/test/test.go:3931: undefined: erre
我的第一个想法是使用正则表达式,但我发现的唯一示例是已经以scheme/prototcol作为前缀的路径


我被卡住了,所以我非常感谢你的想法/建议。我将在go中实现它,但这并不重要。

非常酷的想法。然而,文件名有一个相当通用的格式,所以我怀疑您应该只关注其中的一小部分,而不是全部

如果你打算使用它来进行编程工作,那么你可能认为只接受许多程序员认为好的文件名是可以接受的。即路径中的字符集与[A-Za-z0-9/514;匹配。您还希望查找的是后跟“:\d+”的文件名,并且行规范与其他字符不连续,这些字符看起来可能是行规范的一部分。最后一位可以通过向前和向后环视断言来完成

如果您将其与文件存在性测试(相对于当前目录或指定目录)相结合,那么您就得到了一个可管理的范围和一个健壮的测试

因此,您的文件规范regex如下所示:

(?<![A-Za-z0-9/_.-])([A-Za-z0-9_.-]):(\d+)(?![A-Za-z0-9/_.-])
路径是否以
开头并不重要。无论如何,上述方法都有效,因为
/foo//bar/baz
是一种可接受的路径。与
/foo/bar/./../bar/baz/xyz'\
相同

您应该尝试确保您在这里使用的规范与您的gnome终端认为是链接的一部分的规范一致


关于你是如何完成gnome终端位的详细信息将很高兴看到。这将使这个页面在将来对其他人更有用。

非常酷的想法。然而,文件名有一个相当通用的格式,所以我怀疑您应该只关注其中的一小部分,而不是全部

如果你打算使用它来进行编程工作,那么你可能认为只接受许多程序员认为好的文件名是可以接受的。即路径中的字符集与[A-Za-z0-9/514;匹配。您还希望查找的是后跟“:\d+”的文件名,并且行规范与其他字符不连续,这些字符看起来可能是行规范的一部分。最后一位可以通过向前和向后环视断言来完成

如果您将其与文件存在性测试(相对于当前目录或指定目录)相结合,那么您就得到了一个可管理的范围和一个健壮的测试

因此,您的文件规范regex如下所示:

(?<![A-Za-z0-9/_.-])([A-Za-z0-9_.-]):(\d+)(?![A-Za-z0-9/_.-])
路径是否以
开头并不重要。无论如何,上述方法都有效,因为
/foo//bar/baz
是一种可接受的路径。与
/foo/bar/./../bar/baz/xyz'\
相同

您应该尝试确保您在这里使用的规范与您的gnome终端认为是链接的一部分的规范一致


关于你是如何完成gnome终端位的详细信息将很高兴看到。这将使此页面在将来对其他人更有用。

除了mc0e提供的regexp解决方案外,一旦找到带有文件名的字符串,您可以通过以下方式传递它们:

package main

import (
    "bufio"
    "fmt"
    "os"
    "path/filepath"
)

func checkLine(s string) bool {
    // Insert regex checking logic here. Just checking for blank line now.
    if s == "" {
        return false
    }
    return true
}

func srcerer(s string) (string, error) {
    p, err := filepath.Abs(s)
    if err != nil {
        return "", err
    }
    return "src:///" + p, nil
}

func main() {
    scanner := bufio.NewScanner(os.Stdin)
    for scanner.Scan() {
        v := scanner.Text()
        if checkLine(v) {
            link, err := srcerer(v)
            if err != nil {
                fmt.Fprintln(os.Stderr, "Error:", err)
                return
            }
            fmt.Println(link)
        }
    }
    if err := scanner.Err(); err != nil {
        fmt.Fprintln(os.Stderr, "reading standard input:", err)
    }
    return
}
其中,将上述代码编译成名为
src links
的二进制文件,并给出名为
testlines.txt
的文件,其内容如下:

./test.go:14: undefined: erre
./test.go:16: undefined: erre
./test.go:21: undefined: erre
./test.go:27: undefined: erre
命令
cat testlines.txt | src links
将输出:

src:///home/icholy/gocode/src/test/test.go:14: undefined: erre
src:///home/icholy/gocode/src/test/test.go:16: undefined: erre
src:///home/icholy/gocode/src/test/test.go:21: undefined: erre
src:///home/icholy/gocode/src/test/test.go:27: undefined: erre

除了mc0e提供的regexp解决方案外,一旦找到具有文件名的字符串,您可以通过以下方式对其进行管道传输:

package main

import (
    "bufio"
    "fmt"
    "os"
    "path/filepath"
)

func checkLine(s string) bool {
    // Insert regex checking logic here. Just checking for blank line now.
    if s == "" {
        return false
    }
    return true
}

func srcerer(s string) (string, error) {
    p, err := filepath.Abs(s)
    if err != nil {
        return "", err
    }
    return "src:///" + p, nil
}

func main() {
    scanner := bufio.NewScanner(os.Stdin)
    for scanner.Scan() {
        v := scanner.Text()
        if checkLine(v) {
            link, err := srcerer(v)
            if err != nil {
                fmt.Fprintln(os.Stderr, "Error:", err)
                return
            }
            fmt.Println(link)
        }
    }
    if err := scanner.Err(); err != nil {
        fmt.Fprintln(os.Stderr, "reading standard input:", err)
    }
    return
}
其中,将上述代码编译成名为
src links
的二进制文件,并给出名为
testlines.txt
的文件,其内容如下:

./test.go:14: undefined: erre
./test.go:16: undefined: erre
./test.go:21: undefined: erre
./test.go:27: undefined: erre
命令
cat testlines.txt | src links
将输出:

src:///home/icholy/gocode/src/test/test.go:14: undefined: erre
src:///home/icholy/gocode/src/test/test.go:16: undefined: erre
src:///home/icholy/gocode/src/test/test.go:21: undefined: erre
src:///home/icholy/gocode/src/test/test.go:27: undefined: erre

你可以用grep或awk来做这件事,省去了在go中重新实现它的麻烦…(虽然我不会责怪你把git作为一个学习练习来做)。你可以用grep或awk来做这件事,省去了在go中重新实现它的麻烦…(虽然我不会责怪你把git作为一个学习练习来做)。