【问题标题】:How can I fix this wiki link parsing regular expression?如何修复此 wiki 链接解析正则表达式?
【发布时间】:2011-03-26 12:56:11
【问题描述】:

我有一个旧 wiki,我正在将其转换为一个使用 Markdown 和 [[]] wiki 链接格式的新 wiki。不幸的是,旧 wiki 真的 很旧,并且有 许多 生成链接的方法,包括。 CamelCase、单括号 ([]) wiki 链接等。

我正在转换sed 中的正则表达式,并使用以下正则表达式将独立的 CamelCase 链接转换为双括号 ([[]]) wiki 链接:

s/([^[|])([A-Z][a-z]+[A-Z][A-Za-z]+)([^]|])/\1\[\[\2\]\]\3/g

不幸的是,上述的一个问题(我试图在现有的单括号 wiki 链接中不转换 CamelCase,因为两者兼而有之)是 [BluetoothConnection|UsingBluetoothIndex] 之类的东西将被转换为 [BluetoothConnection|Using[[BluetoothInde]]x]

如何解决此问题并强制匹配更加贪婪,从而失败并且在这种情况下不进行替换?如果sed 的增强正则表达式过于局限,我愿意通过perl 而不是sed

【问题讨论】:

  • 字符串[BluetoothConnection|UsingBluetoothIndex]的预期输出是什么
  • [BluetoothConnection|UsingBluetoothIndex] 应该保持不变,以供以后的正则表达式处理。

标签: regex sed wiki


【解决方案1】:

好的,你可以试试这个:

$ echo "UsingBluetoothIndex" | sed -E 's!([^\[\|]?)([A-Z][a-z]+[A-Z][A-Za-z]+)($|\b|[]|])!\1\[\[\2\]\]\3!g'
Output: [[UsingBluetoothIndex]]

$ echo "[BluetoothConnection|UsingBluetoothIndex]" | sed -E 's!([^\[\|]?)([A-Z][a-z]+[A-Z][A-Za-z]+)($|\b|[]|])!\1\[\[\2\]\]\3!g'
Output: [[[BluetoothConnection]]|[[UsingBluetoothIndex]]]

更新:

好吧,我相信现在我使用perl's negative look behind directive 为您的问题提供了正则表达式。所以这里是:

perl -pe 's#(^|\b)((?![|\[])[A-Z][a-z]+[A-Z][A-Za-z]+(?![|\]]))($|\b)#\[\[\2\]\]#g'

echo "BluetoothConnection" | perl -pe 's#(^|\b)((?![|\[])[A-Z][a-z]+[A-Z][A-Za-z]+(?![|\]]))($|\b)#\[\[\2\]\]#g'
Output: [[BluetoothConnection]]

echo "[BluetoothConnection|UsingBluetoothIndex]" | perl -pe 's#(^|\b)((?![|\[])[A-Z][a-z]+[A-Z][A-Za-z]+(?![|\]]))($|\b)#\[\[\2\]\]#g'
Output: [BluetoothConnection|UsingBluetoothIndex]

它所做的只是检查文本是否不是以'|'开头或 '[' 且不以 |] 结尾,然后将其括在 [[]] 中。

【讨论】:

  • 很遗憾,[BluetoothConnection|UsingBluetoothIndex] 应该保持原样,而不是转换为 [[[BluetoothConnection]]|[[UsingBluetoothIndex]]]
  • 哦,不应该在sed的正则表达式中对字符类中的特殊字符进行反斜杠转义,因为它们不再被认为是特殊的(除了前导'^',虽然'] '&'-'必须放在特定位置才能理解)。见man re_format。至少,在 BSD/Mac OS X(我正在运行)下是这种情况。
  • @morgant:我使用 perl 为您的问题提供了另一种解决方案,请参阅上面的更新部分。
  • 好的,感谢您提供的链接,我现在完全了解 Perl 的外观。我也没有考虑过使用(^|\b)($|\b) 来强制它使用完整的单词边界!我现在正在通过以下管道,它完美地工作:perl -pe "s/(^|\b|_)((?<![\[|])[A-Z][a-z]+[A-Z][A-Za-z]+(?![\]|]))($|\b|_)/\1\[\[\2\]\]\3/g"。 (顺便说一句,在您的示例中,您似乎不小心使用了前瞻而不是后瞻。)关于环视的出色解决方案和教育!
  • @morgant:谢谢,我很高兴它现在以您想要的方式为您工作,是的,您是对的,我使用了消极的前瞻 :)
猜你喜欢
  • 1970-01-01
  • 2018-09-10
  • 1970-01-01
  • 2011-09-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-14
  • 2010-09-05
相关资源
最近更新 更多