【问题标题】:regex: replace hyphens with en-dashes with re.sub正则表达式:用 re.sub 用短划线替换连字符
【发布时间】:2017-12-13 15:19:42
【问题描述】:

我正在使用一个小函数来循环文件,以便将任何连字符 - 替换为破折号 (alt + 0150)。

我使用的函数为相关问题的解决方案添加了一些正则表达式风格 (how to replace a character INSIDE the text content of many files automatically?)

def mychanger(fileName):
  with open(fileName,'r') as file:
    str = file.read()
    str = str.decode("utf-8")
    str = re.sub(r"[^{]{1,4}(-)","–", str).encode("utf-8")
  with open(fileName,'wb') as file:
    file.write(str)

我使用了正则表达式[^{]{1,4}(-),因为搜索实际上是在乳胶回归表上执行的,我只想替换出现在数字周围的连字符。

明确一点:如果我们有真正的乳胶代码,例如\cmidrule(lr){2-4},我想替换所有连字符EXCEPT

  • 在这种情况下,{ 靠近(最多 3-4 个字符)到 hyphen 及其左侧。当然,这个连字符不应该变成破折号,否则乳胶代码会中断。

  • 我认为排除的左侧部分条件对于在正则表达式中编写正确的异常很重要。实际上,在回归表中,您可以使用 -0.062\sym{***}(即连字符最右边的 {)之类的内容,在这种情况下 我确实希望 替换连字符。

我表中的典型行是

variable    &   -2.061\sym{***}&       4.032\sym{**}   &       1.236         \\
            &      (-2.32)         &   (-2.02)         &      (-0.14)    

但是,我的正则表达式似乎不正确。例如,(-1.2) 将被替换为 –1.2,去掉括号。

这里有什么问题? 谢谢!

【问题讨论】:

  • 请向我们展示您希望发生替换的所有实例。
  • 您能否提供您的数据样本以及它未能匹配/错误匹配的地方?
  • 您好,谢谢! @TimBiegeleisen @zwer 只能想到像\cmidrule(lr){2-8} 这样的情况,其中有一个{ 靠近连字符和它的左侧。实际上,在回归表中,您可以使用 -0.062\sym{***}
  • @Noobie 我在下面尝试了一个答案。一点也不干净,但让我们看看我们是否可以对此进行迭代,直到我们得到解决您实际问题的东西。

标签: python regex unicode


【解决方案1】:

我可以提供以下两步替换:

str = "-1 Hello \cmidrule(lr){2-4} range 1-5 other stuff a-5"
str = re.sub(r"((?:^|[^{])\d+)-(\d+[^}])","\\1$\\2", str).encode("utf-8")
str = re.sub(r"(^|[^0-9])-(\d+)","\\1$\\2", str).encode("utf-8")
print(str)

第一个替换目标是所有不是 LaTex 形式 {1-9} 的范围,即不包含在花括号内。第二个替换目标是所有前面带有非数字或字符串开头的数字。

Demo

【讨论】:

  • 太棒了!!,但这对破折号有效吗? (不是美元符号)最终我想要破折号而不是连字符。谢谢!!!
  • @Noobie 由于某些编码问题,我无法让演示使用破折号。只需用破折号替换美元符号,它应该可以工作。无论如何,出于演示的目的,我认为美元符号使替换更清晰,更易于阅读。
  • 这是一个 Python 编码问题,我不会提供太多帮助。
  • @Noobie 你需要在这里付出一些努力。我给了你看似有效的模式,剩下的你可以处理。
【解决方案2】:

re.sub 替换整个匹配项。在这种情况下,包括- 前面的非{ 字符。您可以将该位包含在括号中以创建一个 \1 组并将其包含在您的替换中(您也不需要在您的 周围加上括号):

re.sub(r"([^{]{1,4})-",r"\1–", str)

【讨论】:

  • 它在 python3 repl 中为我工作。你能解释一下@TimBiegeleisen 的意思吗?
  • 我认为@TimBiegeleisen 想说的是,这不仅仅取代了hypen,对吗?
  • 应该(我用 X 替换 ascii 连字符以表示强调):In [18]: str = "(-1.2)" In [19]: re.sub(r"([^{]{1,4})-",r"\1X", str) Out[19]: '(X1.2)'
  • 感谢亚当的帮助。但re.sub(r"([^{]{1,4})-",r"\1X", '-0.079\sym{***}') 给出'-0.079\\sym{***}' 会破坏乳胶代码
  • 这将替换 LaTEX 代码。 See the demo here。我认为正确的正则表达式会比这个答案复杂得多。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-26
  • 2015-11-25
  • 1970-01-01
  • 2015-09-28
  • 2022-11-29
  • 2015-11-30
相关资源
最近更新 更多