例如,根据Wiktionary,这是“ when”的发音。enPR,IPA和X-SAMPA是用于显示发音的不同方案。
when:* {{a|US}} {{enPR|wĕn|hwĕn}}, {{IPA|/wɛn/|/ʍɛn/}}, {{X-SAMPA|/wEn/|/WEn/}}
我想提取该关键字when
及其两个IPA发音,并将它们放在单独的行上:
when wɛn
when ʍɛn
一个单词可能有一个,两个或多个IPA发音,并且可能有也可能没有enPR或X-SAMPA发音。
我在考虑PHP,列表中的列表,但这似乎是过大了,并且我不希望用户必须安装它。有没有办法在awk,sed,cut或其他标准Unix命令行实用程序中执行此操作?
使用sed
,您可以将其编写为:
sed '/\([^:]*\):.*{IPA|\([^}]*\).*/!d;s//\1 \2/;s,/,,g;:1
s/\(\([^ ]*\).*\)|/\1\n\2 /;t1'
上面的命令可以分解如下:
解析输入when: ... {IPA|...}
并删除不匹配的行。
在 /pattern/!d; s//repl/
我们[d]放弃与模式不匹配的行,然后在下一个[s]替换命令中重复使用相同的模式(空模式意味着重用最后一个模式)。代替[d]删除不匹配的行,我们可以通过使用b
而不是使它们保持不变d
,或者如果我们知道所有行都与模式匹配,则可以s/pattern/repl/
直接使用。
/\([^:]*\):.*{IPA|\([^}]*\).*/
该模式将数据分为2个块。第一块是when:
。这段代码\([^:]*\):
说要取走所有字符,直到遇到a为止,:
并暂时保存它。变数(\1
)。
:
最高到(包括)之间的所有字符{IPA|
都将被跳过。所保存的下一位是IPA|
。之后的所有内容。这是通过此代码块来完成的,该代码块\([^}]*\)
表示保存所有代码,直到}
遇到a。这保存在变量(\2
)中。
注意:在sed
任何时候要保存字符串的大部分内容时,都可以将其包装在括号中。他们需要使用a进行转义,以\
使sed
您知道这并不是字面上的括号。像这样:\( savethis \)
。
$ sed 's/\([^:]*\):.*{IPA|\([^}]*\).*/\1 \2/;' sample.txt
when /wɛn/|/ʍɛn/
删除所有正斜杠(/
)
这看起来更复杂,因为它使用了备用分隔符。您通常会使用form s///g
,但是sed
让我们即时创建分隔符,所以我们使用逗号代替(s,,,g
)。该块搜索/
并将其替换为空。
$ sed '/\([^:]*\):.*{IPA|\([^}]*\).*/!d;s//\1 \2/;s,/,,g;' sample.txt
when wɛn|ʍɛn
遍历每个IPA
:1 s/\(\([^ ]*\).*\)|/\1\n\2 /;t1
到目前为止,这是此解决方案中最复杂的部分。很难知道发生了什么,但是此块是一个有条件的分支。
:label command(s) t label
该标签是:1
在指令(或多个)s/\(\([^ ]*\).*\)|/\1\n\2 /;
和t label
是“测试”的是看到如果前面的命令修改的模式空间。如果是这样,则跳转到标签1
,因此t1
。
循环内的命令
如果我们花label ... loop
一秒钟时间,然后增加IPA示例,使其具有3个,则可以看到发生了一些变化。
{{IPA|/wɛn/|/ʍɛn/|/blah/}}
到此为止,我们将使用先前的命令结束此操作。
when wɛn|ʍɛn|blah
如果我们现在运行此命令:
$ echo "when wɛn|ʍɛn|blah" | sed 's/\(\([^ ]*\).*\)|/\1 \2 /;'
我们得到这个:
when wɛn|ʍɛn
when blah
您能看到它现在在做什么吗?是的,我也没有,所以让我们简化一点,取出换行符(\n
)并交换一些较短的字符串。
$ echo "X C1|C2|C3" | sed 's/\(\([^ ]*\).*\)|/\1 \2 /;'
X C1|C2 X C3
现在,这里发生的事情是代码\(\([^ ]*\).*\)|
很聪明,因为它嵌套了括号,以便它们像这样( ( ) )
。内部括号中匹配的是没有空格的任何东西。这就是when
字符串。外部parse匹配所有内容,直到最后一个管道(|
)。
此代码段的另一个有趣之处是,对括号进行排序,以便将外部的存储在\1
内部,而将内部的存储在内部\2
。这是因为sed
根据遇到它们的顺序对它们进行编号。
您可以通过使用附加\1
的和扩展代码片段来使自己相信这一点\2
。
$ echo "X C1|C2|C3" | sed 's/\(\([^ ]*\).*\)|/\1 \1 \1 /;'
X C1|C2 X C1|C2 X C1|C2 C3
$ echo "X C1|C2|C3" | sed 's/\(\([^ ]*\).*\)|/\1 \2 \2 /;'
X C1|C2 X X C
因此,循环内的命令基本上要花X
2倍的时间。一次作为整体的一部分X C1|C2
(外部括号),第二次作为直至空间的任何内容(内部括号)。
返回条件分支
好的,因此分支基本上将在#5中调用该命令,因为IPA的数目超过2。sed
分支构造将继续重新运行该命令,直到该命令不再修改替换为止,然后该命令停止。
$ echo "X C1|C2|C3" | sed ':1 s/\(\([^ ]*\).*\)|/\1\n\2 /; t1'
X C1
X C2
X C3
希望以上内容能在将来对其他路人有所帮助。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句