<p>difflib中没有直接的<code>c</code>代码来显示如您所说的Perl的sdiff中更改的行。但你可以很容易地做一个。在difflib的delta中,“changed lines”也有<code>'- '</code>,但与实际删除的行不同,delta中的下一行被标记为<code>'? '</code>,表示delta的前一个索引中的行是“changed”,而不是删除。delta中这条线的另一个目的是作为“指南”来确定变更在哪条线上。在</p>
<p>因此,如果delta中的一条线被标记为<code>'- '</code>,那么根据delta的接下来几行,有四种不同的情况:</p>
<p><strong>案例1</strong>:通过插入</strong>一些字符修改的行</p>
<pre><code>- The good bad
+ The good the bad
? ++++
</code></pre>
<p><strong>案例2</strong>:通过删除</strong>部分字符来修改行</p>
^{pr2}$
<p><strong>案例3</strong>:通过删除并插入</strong>和/或<strong>替换</strong>一些字符来修改行:</p>
<pre><code>- The good the bad and ugly
? ^^
+ The g00d bad and the ugly
? ^^ ++++
</code></pre>
<p><strong>案例4</strong>:行被<strong>删除</strong></p>
<pre><code>- The good the bad and the ugly
+ Our ratio is less than 0.75!
</code></pre>
<p>如您所见,用<code>'? '</code>标记的行显示了在哪里进行了哪种类型的修改。在</p>
<p>请注意,如果被比较的两行之间的<a href="http://docs.python.org/library/difflib.html#difflib.SequenceMatcher.ratio" rel="nofollow">^{<cd6>}</a>值小于0.75,difflib会认为删除一行。这是我通过测试发现的一个值。在</p>
<p>所以要推断一条线是改变了的,你可以这样做。这将返回带有代码“c”标记的已更改行和标记为“u”的未更改行的差异,就像在Perl的sdiff中:</p>
<pre><code>def sdiffer(s1, s2):
differ = difflib.Differ()
diffs = list(differ.compare(s1, s2))
i = 0
sdiffs = []
length = len(diffs)
while i < length:
line = diffs[i][2:]
if diffs[i].startswith(' '):
sdiffs.append(('u', line))
elif diffs[i].startswith('+ '):
sdiffs.append(('+', line))
elif diffs[i].startswith('- '):
if i+1 < length and diffs[i+1].startswith('? '): # then diffs[i+2] starts with ('+ '), obviously
sdiffs.append(('c', line))
i += 3 if i + 3 < length and diffs[i + 3].startswith('? ') else 2
elif diffs[i+1].startswith('+ ') and i+2<length and diffs[i+2].startswith('? '):
sdiffs.append(('c', line))
i += 2
else:
sdiffs.append(('-', line))
i += 1
return sdiffs
</code></pre>
<p>希望有帮助。在</p>
<p>这是一个老问题,所以我不确定我的努力会得到多好的回报。<code>:-(</code>我就是忍不住回答这个问题,因为我最近一直在使用difflib。</em></sub></p>