【问题标题】:TCL regexp exampleTCL 正则表达式示例
【发布时间】:2011-07-01 05:12:07
【问题描述】:

我想通过编写正则表达式来获取以 abc_ 或 xyz_ 开头的字符串中的单词。 这是我的脚本:

[regexp -nocase -- {.*\s+(abc_|xyz_\S+)\s+.*} $str all necessaryStr]

因此,如果我在 str1 和 str2 上应用上述编写的正则表达式,我想从 $str1 中获取“xyz_hello”,从 $str2 中获取“abc_bye”。

set str1 "gfrdgasjklh dlasd =-0-489 xyz_hello sddf 89rn sf n9"
set str2 "dytfasjklh abc_bye dlasd =-0tyj-489 sddf tyj89rn sjf n9"

但是我的正则表达式不起作用。我的问题是:

1) 我的正则表达式有什么问题? 2) 用正则表达式找一些预定义前缀开头的作品好还是用字符串函数(字符串匹配左右)更好?

【问题讨论】:

    标签: regex string tcl string-matching


    【解决方案1】:

    在您的问题中不清楚什么是单词。是否允许进一步下划线?允许数字吗? “仅由前缀组成的单词”怎么样,例如“abc_”还是“xyz”?

    做出保守的假设(根据您的示例),您只需要英文字母表中的字母,至少还有一个字符,并且您不关心大小写,您可以简化您的正则表达式:

    [regexp -nocase -- {\m(abc_|xyz_)[a-zA-Z]+} $str match]
    

    这会将match 设置为匹配的单词。如果您对单词的定义与我的假设不同,您可以替换方括号的内容。

    关于是否更喜欢正则表达式而不是字符串函数的第二个问题将取决于上下文,并可能导致主观领域。

    需要考虑的一些事项:

    • 性能真的很重要吗?除非您在紧密循环中进行搜索,或者搜索非常长的字符串,否则我怀疑任何性能差异都不会相关。等到您遇到性能问题,然后分析您的应用程序以查看瓶颈所在,然后您可以测试替代实现。
    • 是否方便取决于必须编写和维护代码的程序员的偏好。他们喜欢/讨厌使用正则表达式吗?
    • 使用正则表达式可能会提供更大的灵活性,但它可能会以可读性为代价。

    我的建议是使用您最熟悉的那个。为您的代码编写一组良好的单元测试,然后仅当您在分析期间发现瓶颈时才进行优化。

    【讨论】:

    • 您需要在模式的开头添加\m 或\y 以确保您匹配单词的开头——因为它会匹配“zzzabc_zzz "
    • 是的,从最初的问题中我并不清楚“zzzabc_zzz”之类的内容是否应该匹配 - 或“0abc_x”、“abc_x”等.由于现在从其他cmets中很清楚,我将更新我的答案。干杯。
    【解决方案2】:

    根据您所写的内容,您似乎是以abc_ 或xyz_(无论如何)开头的单词,之后只有字母。匹配这个的一个很好的第一次尝试是这样的:

    regexp -nocase -- {\y(?:abc_|xyz_)[a-z]+} $str match
    

    它的特点是:

    • \y 表示这只匹配单词开头(理论上也是单词结尾,但我们在所有情况下都跟在一个字母后面!)
    • (?:…) 正在分组而不捕获
    • 贪婪匹配意味着我们会得到所有的单词(假设它只表示来自 UNICODE ASCII 范围的字母)。考虑使用\w 或\S 而不是[a-z],但这些确实会改变匹配内容的语义(\w 会告诉你程序标识符中通常允许哪些符号,\S 会给你非空格)。

    【讨论】:

      【解决方案3】:

      我已经解决了: [regexp -nocase -- {.*\s+((abc_|xyz_)\S+)\s+.*} $str all requiredStr ]

      但仍然想知道正则表达式是最好的解决方案还是字符串函数更好(更快、方便、灵活)。

      【讨论】:

      • 这不适用于您在问题中提供的示例。 (除非您删除星号。)您的问题并未明确说明您想要匹配的内容。从这个答案看来,您想要匹配前缀“abc_”或“xyz-_”之后的任何非空白字符。请参阅我的答案以获得更简单的正则表达式。
      • 我想从 $str1 获取“xyz_hello”,从 $str2 获取“abc_bye”。它工作正常。 (只是,请注意,我将“xyz_hello”和“abc_bye”标记为粗体,但本网站没有将它们设为粗体,而是在我要匹配的单词之前和之后包含“**”符号。对不起。
      • 啊,格式问题,我明白了。从原始问题中仍然不清楚在更一般的情况下您想要匹配什么。我们只能根据您自己的解决方案冒险猜测。那么这些字符串呢:“abc_”、“xabc_”、“abc_x”、“xabc_”、“xabc_x”、“abc_x”?它们都不匹配您的正则表达式,因为它在单词前后强制使用空格。那么“ abc_.2/&* ”呢?那将匹配。这都是故意的吗?
      • 也许您的正则表达式足以满足您的需求 - 我只是想说明潜在问题:)
      • 谢谢,但它确实是两边的空格:)
      猜你喜欢
      • 2016-06-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多